diff --git a/hooks/useActivities.tsx b/hooks/useActivities.tsx deleted file mode 100644 index 69617a303..000000000 --- a/hooks/useActivities.tsx +++ /dev/null @@ -1,7 +0,0 @@ -const useActivities = () => { - return { - activities: [], - }; -}; - -export default useActivities; diff --git a/hooks/useClickOutsideSelect.tsx b/hooks/useClickOutsideSelect.tsx deleted file mode 100644 index f777d82e4..000000000 --- a/hooks/useClickOutsideSelect.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { useEffect, useRef, useState } from "react"; - -const useClickOutsideSelect = () => { - const selectRef = useRef() as any; - const [isVisibleSelect, setIsVisibleSelect] = useState(false); - - useEffect(() => { - const handleClose = (e: any) => { - if (selectRef.current && !selectRef.current.contains(e.target)) - setIsVisibleSelect(false); - }; - - document.addEventListener("mousedown", handleClose); - - return () => document.removeEventListener("mousedown", handleClose); - }, [selectRef]); - - return { - isVisibleSelect, - setIsVisibleSelect, - selectRef, - }; -}; - -export default useClickOutsideSelect; diff --git a/hooks/useContainerHeight.tsx b/hooks/useContainerHeight.tsx deleted file mode 100644 index 76e6a8680..000000000 --- a/hooks/useContainerHeight.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { useEffect, useRef, useState } from "react"; - -const useContainerHeight = () => { - const containerRef = useRef(null); - const [containerHeight, setContainerHeight] = useState(0); - - useEffect(() => { - const checkHeight = () => { - if (containerRef.current) { - setTimeout(() => { - const rect = containerRef.current?.getBoundingClientRect(); - const height = rect?.height; - setContainerHeight(height ? height : 0); - }, 350); - } - }; - - checkHeight(); - }); - - return { containerRef, containerHeight }; -}; - -export default useContainerHeight; \ No newline at end of file diff --git a/hooks/useContentCalendar.tsx b/hooks/useContentCalendar.tsx deleted file mode 100644 index b647efd94..000000000 --- a/hooks/useContentCalendar.tsx +++ /dev/null @@ -1,3 +0,0 @@ -const useContentCalendar = () => {}; - -export default useContentCalendar; diff --git a/hooks/useCsrfToken.tsx b/hooks/useCsrfToken.tsx deleted file mode 100644 index f4c5e13e9..000000000 --- a/hooks/useCsrfToken.tsx +++ /dev/null @@ -1,13 +0,0 @@ -export function useCsrfToken() { - if (typeof document === "undefined") { - return ""; - } - - const meta = document.querySelector('meta[name="csrf-token"]'); - - if (!meta) { - return ""; - } - - return meta.getAttribute("content") ?? ""; -} diff --git a/hooks/useHandleManager.tsx b/hooks/useHandleManager.tsx deleted file mode 100644 index 8b3f68af2..000000000 --- a/hooks/useHandleManager.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { useState } from "react"; - -type Handles = Record; - -interface UseHandleManagerProps { - handles: Handles; - onHandlesChange: (handles: Handles) => void; -} - -export const useHandleManager = ({ - handles, - onHandlesChange, -}: UseHandleManagerProps) => { - const [removingPlatform, setRemovingPlatform] = useState(null); - - const handleRemove = (platform: string) => { - setRemovingPlatform(platform); - setTimeout(() => { - const newHandles = { ...handles }; - delete newHandles[platform]; - onHandlesChange(newHandles); - setRemovingPlatform(null); - }, 300); - }; - - const handleChange = ( - e: React.ChangeEvent, - platform: string - ) => { - onHandlesChange({ - ...handles, - [platform]: e.target.value, - }); - }; - - return { - removingPlatform, - handleRemove, - handleChange, - }; -}; diff --git a/hooks/useMermaid.ts b/hooks/useMermaid.ts deleted file mode 100644 index 206df3b10..000000000 --- a/hooks/useMermaid.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { useEffect, useId, useRef, useState } from "react"; -import styles from '../components/Chat/markdown.module.css'; // Import the CSS module - -type MermaidApi = { - run: (options: { nodes: HTMLElement[] }) => void; - initialize: (config: Record) => void; -}; - -export const useMermaid = ({ - id, - chart -}: { - id?: string - chart: string -}) => { - const containerRef = useRef(null); - const generatedId = `mermaid-diagram-${useId()}`; - const uniqueId = id || generatedId; - const mermaidRef = useRef(null); - const [isLibraryLoaded, setIsLibraryLoaded] = useState(false); - const [hasError, setHasError] = useState(false); - - useEffect(() => { - let didCancel = false; - - const loadMermaid = async () => { - try { - // @ts-expect-error - TypeScript cannot analyze remote modules (Replaced ts-ignore) - const mermaidModule = await import(/* webpackIgnore: true */ 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs'); - const mermaid = mermaidModule.default || mermaidModule; - - if (!didCancel) { - mermaidRef.current = mermaid; - setIsLibraryLoaded(true); - setHasError(false); - } - } catch (error) { - if (!didCancel) { - console.error('Failed to dynamically import Mermaid:', error, uniqueId); - } - } - }; - - // Only attempt import if not already loaded - if (!mermaidRef.current) { - loadMermaid(); - } - - // Cleanup function to set flag if component unmounts during import - return () => { - didCancel = true; - }; - }, [uniqueId]); // Run only once on mount - - useEffect(() => { - // Render/re-render the chart when the library is loaded and the chart changes - if (isLibraryLoaded && mermaidRef.current && containerRef.current) { - const mermaid = mermaidRef.current; - const element = containerRef.current; - - // Reset error state before attempting to render - setHasError(false); - - // Ensure the container is clean before rendering - element.innerHTML = chart; // Set content for mermaid to process - element.removeAttribute('data-processed'); - - try { - mermaid.run({ nodes: [element] }); - // Ensure visibility is set correctly after successful render - element.style.visibility = 'visible'; - } catch (error) { - console.error('Mermaid rendering failed:', error, uniqueId); - // Set error state to true on failure - setHasError(true); - // Clear the container content on error to prevent showing raw code or old diagrams - element.innerHTML = ''; - // Hide the container to avoid empty space if needed, or let fallback handle layout - element.style.visibility = 'hidden'; - } - } else if (isLibraryLoaded && !containerRef.current) { - // Handle case where ref might be null unexpectedly after load - console.warn('Mermaid container ref not available after library load:', uniqueId); - setHasError(true); // Indicate an error state - } - }, [isLibraryLoaded, chart, uniqueId]); // Depend on load state and chart content - - useEffect(() => { - const parent = containerRef.current?.parentElement as HTMLElement | null; - const grandparent = parent?.parentElement as HTMLElement | null; - - if (parent) { - parent.classList.add(styles.mermaidParentOverride); - } - if (grandparent) { - grandparent.classList.add(styles.mermaidGrandparentOverride); - } - - // Cleanup function to remove classes when component unmounts or dependencies change - return () => { - if (parent) { - parent.classList.remove(styles.mermaidParentOverride); - } - if (grandparent) { - grandparent.classList.remove(styles.mermaidGrandparentOverride); - } - }; - }, [isLibraryLoaded, hasError, chart]); // Keep dependencies as they are working - - return { isLibraryLoaded, hasError, uniqueId, containerRef }; -}; - diff --git a/hooks/useResearchTimer.ts b/hooks/useResearchTimer.ts deleted file mode 100644 index def498410..000000000 --- a/hooks/useResearchTimer.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { useState, useEffect } from "react"; - -const ACTIVITY_MESSAGES = [ - "gathering sources and creating your report", - "searching hundreds of sources", - "analyzing expert insights", - "synthesizing research data", - "compiling comprehensive analysis", -]; - -interface UseResearchTimerResult { - elapsedSeconds: number; - messageIndex: number; - activityMessages: string[]; -} - -export function useResearchTimer(isActive: boolean): UseResearchTimerResult { - const [elapsedSeconds, setElapsedSeconds] = useState(0); - const [messageIndex, setMessageIndex] = useState(0); - - // Timer for elapsed time - increments every second when active - useEffect(() => { - if (!isActive) { - setElapsedSeconds(0); - return; - } - - const timer = setInterval(() => { - setElapsedSeconds(prev => prev + 1); - }, 1000); - - return () => clearInterval(timer); - }, [isActive]); - - // Rotate activity messages every 5 seconds when active - useEffect(() => { - if (!isActive) { - setMessageIndex(0); - return; - } - - const messageTimer = setInterval(() => { - setMessageIndex(prev => (prev + 1) % ACTIVITY_MESSAGES.length); - }, 5000); - - return () => clearInterval(messageTimer); - }, [isActive]); - - return { - elapsedSeconds, - messageIndex, - activityMessages: ACTIVITY_MESSAGES, - }; -} - diff --git a/hooks/useTypingAnimation.ts b/hooks/useTypingAnimation.ts deleted file mode 100644 index e66a6abf4..000000000 --- a/hooks/useTypingAnimation.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { useState, useEffect } from 'react'; - -/** - * A custom hook that creates a typing animation effect - * - * @param words Array of words to animate typing - * @param isActive Whether the animation should be active - * @param typingSpeed Speed for typing animation in ms - * @param deletingSpeed Speed for deleting animation in ms - * @param pauseTime Time to pause after typing a word in ms - */ -export function useTypingAnimation( - words: string[], - isActive: boolean, - typingSpeed = 200, - deletingSpeed = 100, - pauseTime = 1000 -) { - const [currentWord, setCurrentWord] = useState(""); - const [isDeleting, setIsDeleting] = useState(false); - const [wordIndex, setWordIndex] = useState(0); - - useEffect(() => { - if (!isActive) return; - - const currentFullWord = words[wordIndex]; - - const typeNextCharacter = () => { - if (isDeleting) { - // Deleting logic - if (currentWord.length > 0) { - setCurrentWord((prev) => prev.slice(0, -1)); - } else { - setIsDeleting(false); - setWordIndex((prev) => (prev + 1) % words.length); - } - } else { - // Typing logic - if (currentWord.length < currentFullWord.length) { - setCurrentWord((prev) => currentFullWord.slice(0, prev.length + 1)); - } else { - setTimeout(() => setIsDeleting(true), pauseTime); - } - } - }; - - const timer = setTimeout( - typeNextCharacter, - isDeleting ? deletingSpeed : typingSpeed - ); - - return () => clearTimeout(timer); - }, [currentWord, isDeleting, wordIndex, words, isActive, typingSpeed, deletingSpeed, pauseTime]); - - return { currentWord }; -} - -export default useTypingAnimation; \ No newline at end of file