import { createContext, FC, useContext, useEffect, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; import { ApiAdapterUtils } from "@dndbeyond/character-rules-engine"; import { builderActions } from "~/tools/js/CharacterBuilder/actions"; import { apiCreatorSelectors } from "~/tools/js/Shared/selectors"; import { ClassDefinitionContract as ClassDef } from "~/types"; /** * A context to provide data to the application without causing a re-render or * unnecessary fetches and transforms. This context is used in places where * character-specific data is not needed. */ export interface ClassContextType { query: string; setQuery: (query: string) => void; filteredClasses: Array; allClasses: Array; handleSelectClass: (id: number) => void; isLoading: boolean; isModalShowing: boolean; closeModal: () => void; } export const ClassContext = createContext(null!); export const ClassProvider: FC = ({ children }) => { const dispatch = useDispatch(); const [query, setQuery] = useState(""); const [allClasses, setAllClasses] = useState>([]); const [isLoading, setIsLoading] = useState(true); const [isModalShowing, setIsModalShowing] = useState(false); const closeModal = () => setIsModalShowing(false); const loadClasses = useSelector(apiCreatorSelectors.makeLoadAvailableClasses); const handleSelectClass = (id: number) => { const entity = allClasses.find((c) => c.id === id); if (entity) { dispatch(builderActions.confirmClassSet(entity)); setIsModalShowing(true); window.scrollTo(0, 0); } }; // Handle searching through items const filteredClasses = query ? allClasses.filter((c) => c.name?.toLowerCase().includes(query.toLowerCase()) ) : allClasses; useEffect(() => { const getAllData = async () => { // Load all classes const response = await loadClasses(); const classes = ApiAdapterUtils.getResponseData(response) || []; setAllClasses(classes); if (classes.length > 0) { setIsLoading(false); } }; getAllData(); }, [loadClasses]); return ( {children} ); }; export const useClassContext = () => { return useContext(ClassContext); };