First Commit
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
import { use } from 'react';
|
||||
|
||||
// @project
|
||||
import { ConfigContext } from '@/contexts/ConfigContext';
|
||||
|
||||
/*************************** HOOKS - CONFIG ***************************/
|
||||
|
||||
/**
|
||||
* Custom hook to access the application's configuration context.
|
||||
*
|
||||
* This hook provides an easy way to consume the `ConfigContext`,
|
||||
* which typically contains application-wide settings like themes,
|
||||
* layouts, or other configurable options.
|
||||
*
|
||||
* @returns {any} The value provided by the `ConfigContext`.
|
||||
* Ensure that the component using this hook is wrapped with a `ConfigProvider`.
|
||||
*/
|
||||
|
||||
export default function useConfig() {
|
||||
const context = use(ConfigContext);
|
||||
|
||||
if (!context) throw new Error('useSConfig must be use inside ConfigProvider');
|
||||
|
||||
return context;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
|
||||
/*************************** HOOKS - LOCAL STORAGE ***************************/
|
||||
|
||||
export default function useLocalStorage(key, defaultValue) {
|
||||
// Load initial state from localStorage or fallback to default
|
||||
const readValue = () => {
|
||||
if (typeof window === 'undefined') return defaultValue;
|
||||
|
||||
try {
|
||||
const item = localStorage.getItem(key);
|
||||
return item ? JSON.parse(item) : defaultValue;
|
||||
} catch (err) {
|
||||
console.warn(`Error reading localStorage key “${key}”:`, err);
|
||||
return defaultValue;
|
||||
}
|
||||
};
|
||||
|
||||
const [state, setState] = useState(readValue);
|
||||
|
||||
// Sync to localStorage whenever state changes
|
||||
useEffect(() => {
|
||||
try {
|
||||
localStorage.setItem(key, JSON.stringify(state));
|
||||
} catch (err) {
|
||||
console.warn(`Error setting localStorage key “${key}”:`, err);
|
||||
}
|
||||
}, [key, state]);
|
||||
|
||||
// Update single field
|
||||
const setField = useCallback((key, value) => {
|
||||
setState((prev) => ({
|
||||
...prev,
|
||||
[key]: value
|
||||
}));
|
||||
}, []);
|
||||
|
||||
// Reset to defaults
|
||||
const resetState = useCallback(() => {
|
||||
setState(defaultValue);
|
||||
localStorage.setItem(key, JSON.stringify(defaultValue));
|
||||
}, [defaultValue, key]);
|
||||
|
||||
return { state, setState, setField, resetState };
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
import { useEffect } from 'react';
|
||||
|
||||
/*************************** MENU COLLAPSED - RECURSIVE FUNCTION ***************************/
|
||||
|
||||
/**
|
||||
* Recursively traverses menu items to find and open the correct parent menu.
|
||||
* If a menu item matches the current pathname, it marks the corresponding menu as selected and opens it.
|
||||
*
|
||||
* @param {NavItemType[]} items - List of menu items.
|
||||
* @param {string} pathname - Current route pathname.
|
||||
* @param {string | undefined} menuId - ID of the menu to be set as selected.
|
||||
* @param {SetState<string | null>} setSelected - Function to update the selected menu.
|
||||
* @param {Dispatch<SetStateAction<boolean>>} setOpen - Function to update the open state.
|
||||
*/
|
||||
|
||||
function setParentOpenedMenu(items, pathname, menuId, setSelected, setOpen) {
|
||||
for (const item of items) {
|
||||
// Recursively check child menus
|
||||
if (item.children?.length) {
|
||||
setParentOpenedMenu(item.children, pathname, menuId, setSelected, setOpen);
|
||||
}
|
||||
|
||||
if (item.url === pathname) {
|
||||
setSelected(menuId ?? null);
|
||||
setOpen(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*************************** MENU COLLAPSED - HOOK ***************************/
|
||||
|
||||
/**
|
||||
* Hook to handle menu collapse behavior based on the current route.
|
||||
* Automatically expands the parent menu of the active route item.
|
||||
*
|
||||
* @param {NavItemType} menu - The menu object containing items.
|
||||
* @param {string} pathname - Current route pathname.
|
||||
* @param {boolean} miniMenuOpened - Flag indicating if the mini menu is open.
|
||||
* @param {SetState<string | null>} setSelected - Function to update selected menu state.
|
||||
* @param {Dispatch<SetStateAction<boolean>>} setOpen - Function to update menu open state.
|
||||
* @param {SetState<HTMLElement>} setAnchorEl - Function to update the anchor element state.
|
||||
*/
|
||||
|
||||
export default function useMenuCollapse(menu, pathname, miniMenuOpened, setSelected, setOpen, setAnchorEl) {
|
||||
useEffect(() => {
|
||||
setOpen(false); // Close the menu initially
|
||||
|
||||
// Reset selection based on menu state
|
||||
if (!miniMenuOpened) {
|
||||
setSelected(null);
|
||||
} else {
|
||||
if (setAnchorEl) setAnchorEl(null);
|
||||
}
|
||||
|
||||
// If menu has children, determine which should be opened
|
||||
if (menu.children?.length) {
|
||||
setParentOpenedMenu(menu.children, pathname, menu.id, setSelected, setOpen);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [pathname, menu.children]);
|
||||
}
|
||||
Reference in New Issue
Block a user