ALwrity Version 0.5.0 (Fastapi + React )

This commit is contained in:
ajaysi
2025-08-06 12:48:02 +05:30
parent f28a919caa
commit 32f97fa6b3
476 changed files with 115544 additions and 28747 deletions

View File

@@ -0,0 +1,120 @@
import { useState, useEffect } from 'react';
import { DashboardState, SnackbarState } from '../components/shared/types';
const useDashboardState = () => {
const [state, setState] = useState<DashboardState>({
loading: true,
error: null,
searchQuery: '',
selectedCategory: null,
selectedSubCategory: null,
favorites: [],
snackbar: {
open: false,
message: '',
severity: 'info',
},
});
// Load favorites from localStorage
useEffect(() => {
const savedFavorites = localStorage.getItem('alwrity-favorites');
if (savedFavorites) {
setState(prev => ({
...prev,
favorites: JSON.parse(savedFavorites),
loading: false,
}));
} else {
setState(prev => ({ ...prev, loading: false }));
}
}, []);
// Save favorites to localStorage
const toggleFavorite = (toolName: string) => {
const newFavorites = state.favorites.includes(toolName)
? state.favorites.filter(f => f !== toolName)
: [...state.favorites, toolName];
setState(prev => ({
...prev,
favorites: newFavorites,
}));
localStorage.setItem('alwrity-favorites', JSON.stringify(newFavorites));
showSnackbar(
state.favorites.includes(toolName) ? 'Removed from favorites' : 'Added to favorites',
'success'
);
};
const setSearchQuery = (query: string) => {
setState(prev => ({ ...prev, searchQuery: query }));
};
const setSelectedCategory = (category: string | null) => {
setState(prev => ({
...prev,
selectedCategory: category,
selectedSubCategory: null, // Reset sub-category when changing main category
}));
};
const setSelectedSubCategory = (subCategory: string | null) => {
setState(prev => ({ ...prev, selectedSubCategory: subCategory }));
};
const setError = (error: string | null) => {
setState(prev => ({ ...prev, error }));
};
const setLoading = (loading: boolean) => {
setState(prev => ({ ...prev, loading }));
};
const showSnackbar = (message: string, severity: SnackbarState['severity'] = 'info') => {
setState(prev => ({
...prev,
snackbar: {
open: true,
message,
severity,
},
}));
};
const hideSnackbar = () => {
setState(prev => ({
...prev,
snackbar: {
...prev.snackbar,
open: false,
},
}));
};
const clearFilters = () => {
setState(prev => ({
...prev,
searchQuery: '',
selectedCategory: null,
selectedSubCategory: null,
}));
};
return {
state,
toggleFavorite,
setSearchQuery,
setSelectedCategory,
setSelectedSubCategory,
setError,
setLoading,
showSnackbar,
hideSnackbar,
clearFilters,
};
};
export default useDashboardState;

View File

@@ -0,0 +1,54 @@
import { useEffect, useCallback, useRef } from 'react';
export const usePerformanceOptimization = () => {
const animationFrameRef = useRef<number>();
const timeoutRef = useRef<NodeJS.Timeout>();
// Debounce function for expensive operations
const debounce = useCallback((func: Function, delay: number) => {
return (...args: any[]) => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
timeoutRef.current = setTimeout(() => func(...args), delay);
};
}, []);
// Throttle function for scroll/resize events
const throttle = useCallback((func: Function, delay: number) => {
let lastCall = 0;
return (...args: any[]) => {
const now = Date.now();
if (now - lastCall >= delay) {
lastCall = now;
func(...args);
}
};
}, []);
// Optimize animations with requestAnimationFrame
const smoothAnimation = useCallback((callback: () => void) => {
if (animationFrameRef.current) {
cancelAnimationFrame(animationFrameRef.current);
}
animationFrameRef.current = requestAnimationFrame(callback);
}, []);
// Cleanup on unmount
useEffect(() => {
return () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
if (animationFrameRef.current) {
cancelAnimationFrame(animationFrameRef.current);
}
};
}, []);
return {
debounce,
throttle,
smoothAnimation,
};
};