AI podcast maker performance optimizations
This commit is contained in:
@@ -508,6 +508,7 @@ const ContentLifecyclePillars: React.FC = () => {
|
||||
borderRadius: 2,
|
||||
mb: 4,
|
||||
position: 'relative', // For hero section positioning
|
||||
minHeight: '200px', // Reserve space for hero section to prevent layout shift
|
||||
}}
|
||||
>
|
||||
<Container maxWidth="xl">
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState, useMemo, useCallback } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Container,
|
||||
@@ -84,15 +84,17 @@ const MainDashboard: React.FC = () => {
|
||||
initializeWorkflow();
|
||||
}, [generateDailyWorkflow]);
|
||||
|
||||
// Debug logging for workflow state
|
||||
// Debug logging for workflow state (only in development)
|
||||
React.useEffect(() => {
|
||||
console.log('Workflow Debug:', {
|
||||
currentWorkflow,
|
||||
workflowProgress,
|
||||
isWorkflowActive: currentWorkflow?.workflowStatus === 'in_progress',
|
||||
workflowStatus: currentWorkflow?.workflowStatus,
|
||||
hasWorkflow: !!currentWorkflow
|
||||
});
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
console.log('Workflow Debug:', {
|
||||
currentWorkflow,
|
||||
workflowProgress,
|
||||
isWorkflowActive: currentWorkflow?.workflowStatus === 'in_progress',
|
||||
workflowStatus: currentWorkflow?.workflowStatus,
|
||||
hasWorkflow: !!currentWorkflow
|
||||
});
|
||||
}
|
||||
}, [currentWorkflow, workflowProgress]);
|
||||
|
||||
// State to track if we need to start a newly generated workflow
|
||||
@@ -166,42 +168,50 @@ const MainDashboard: React.FC = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleToolClick = (tool: Tool) => {
|
||||
console.log('Navigating to tool:', tool.path);
|
||||
const handleToolClick = useCallback((tool: Tool) => {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
console.log('Navigating to tool:', tool.path);
|
||||
}
|
||||
if (tool.path) {
|
||||
navigate(tool.path);
|
||||
return;
|
||||
}
|
||||
showSnackbar(`Launching ${tool.name}...`, 'info');
|
||||
};
|
||||
}, [navigate, showSnackbar]);
|
||||
|
||||
// Handle category click to open modal
|
||||
const handleCategoryClick = (categoryName: string | null, categoryData?: any) => {
|
||||
const handleCategoryClick = useCallback((categoryName: string | null, categoryData?: any) => {
|
||||
setModalCategoryName(categoryName);
|
||||
setModalCategory(categoryData);
|
||||
setToolsModalOpen(true);
|
||||
};
|
||||
}, []);
|
||||
|
||||
// Memoize search results computation
|
||||
const searchResultsMemo = useMemo(() => {
|
||||
if (!searchQuery || searchQuery.length < 2) return [];
|
||||
|
||||
// Get all tools from all categories that match search
|
||||
const allTools: Tool[] = [];
|
||||
Object.values(toolCategories).forEach(category => {
|
||||
if (category) {
|
||||
const tools = getToolsForCategory(category, null);
|
||||
allTools.push(...tools);
|
||||
}
|
||||
});
|
||||
|
||||
const queryLower = searchQuery.toLowerCase();
|
||||
return allTools.filter(tool =>
|
||||
tool.name.toLowerCase().includes(queryLower) ||
|
||||
tool.description.toLowerCase().includes(queryLower) ||
|
||||
tool.features.some(feature => feature.toLowerCase().includes(queryLower))
|
||||
);
|
||||
}, [searchQuery]);
|
||||
|
||||
// Handle search to show results in modal with debouncing
|
||||
React.useEffect(() => {
|
||||
if (searchQuery && searchQuery.length >= 2) { // Only search after 2+ characters
|
||||
if (searchQuery && searchQuery.length >= 2) {
|
||||
const timeoutId = setTimeout(() => {
|
||||
// Get all tools from all categories that match search
|
||||
const allTools: Tool[] = [];
|
||||
Object.values(toolCategories).forEach(category => {
|
||||
if (category) {
|
||||
const tools = getToolsForCategory(category, null);
|
||||
allTools.push(...tools);
|
||||
}
|
||||
});
|
||||
|
||||
const filtered = allTools.filter(tool =>
|
||||
tool.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||
tool.description.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||
tool.features.some(feature => feature.toLowerCase().includes(searchQuery.toLowerCase()))
|
||||
);
|
||||
|
||||
setSearchResults(filtered);
|
||||
setSearchResults(searchResultsMemo);
|
||||
setModalCategoryName(null);
|
||||
setModalCategory(null);
|
||||
setToolsModalOpen(true);
|
||||
@@ -212,10 +222,10 @@ const MainDashboard: React.FC = () => {
|
||||
// Close modal if search query is too short
|
||||
setToolsModalOpen(false);
|
||||
}
|
||||
}, [searchQuery]);
|
||||
}, [searchQuery, searchResultsMemo]);
|
||||
|
||||
// Close modal and clear search
|
||||
const handleCloseModal = () => {
|
||||
const handleCloseModal = useCallback(() => {
|
||||
setToolsModalOpen(false);
|
||||
setModalCategoryName(null);
|
||||
setModalCategory(null);
|
||||
@@ -223,7 +233,7 @@ const MainDashboard: React.FC = () => {
|
||||
if (searchQuery) {
|
||||
setSearchQuery('');
|
||||
}
|
||||
};
|
||||
}, [searchQuery, setSearchQuery]);
|
||||
|
||||
// Note: filteredCategories removed as it's not used in the current implementation
|
||||
|
||||
@@ -242,19 +252,21 @@ const MainDashboard: React.FC = () => {
|
||||
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%)',
|
||||
padding: theme.spacing(4),
|
||||
position: 'relative',
|
||||
overflow: 'hidden', // Prevent layout shifts from pseudo-elements
|
||||
'&::before': {
|
||||
content: '""',
|
||||
position: 'absolute',
|
||||
position: 'fixed', // Changed from absolute to fixed to prevent layout shifts
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
background: 'url("data:image/svg+xml,%3Csvg width="80" height="80" viewBox="0 0 80 80" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="none" fill-rule="evenodd"%3E%3Cg fill="%23ffffff" fill-opacity="0.03"%3E%3Ccircle cx="40" cy="40" r="3"/%3E%3C/g%3E%3C/g%3E%3C/svg%3E")',
|
||||
pointerEvents: 'none',
|
||||
willChange: 'transform', // Optimize for animations
|
||||
},
|
||||
'&::after': {
|
||||
content: '""',
|
||||
position: 'absolute',
|
||||
position: 'fixed', // Changed from absolute to fixed to prevent layout shifts
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
width: '600px',
|
||||
@@ -263,6 +275,7 @@ const MainDashboard: React.FC = () => {
|
||||
transform: 'translate(-50%, -50%)',
|
||||
pointerEvents: 'none',
|
||||
zIndex: 0,
|
||||
willChange: 'transform', // Optimize for animations
|
||||
},
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -55,6 +55,8 @@ const WorkflowHeroSection: React.FC<WorkflowHeroSectionProps> = ({
|
||||
justifyContent: 'center',
|
||||
borderRadius: 2, // Match the parent container's border radius
|
||||
px: 2, // Add horizontal padding to constrain width
|
||||
minHeight: '200px', // Reserve space to prevent layout shift
|
||||
willChange: 'transform', // Optimize for animations
|
||||
}}
|
||||
>
|
||||
{/* Hero Content - Full Coverage */}
|
||||
@@ -130,6 +132,7 @@ const WorkflowHeroSection: React.FC<WorkflowHeroSectionProps> = ({
|
||||
initial={{ opacity: 0, scale: 0.9 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ duration: 0.8, delay: 0.2 }}
|
||||
style={{ width: '100%' }} // Prevent width changes
|
||||
>
|
||||
{/* Main Heading with Rocket */}
|
||||
<Box sx={{
|
||||
@@ -137,7 +140,8 @@ const WorkflowHeroSection: React.FC<WorkflowHeroSectionProps> = ({
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: 2,
|
||||
mb: 2
|
||||
mb: 2,
|
||||
minHeight: '48px', // Reserve space for heading to prevent layout shift
|
||||
}}>
|
||||
<Typography
|
||||
variant={isMobile ? "h5" : "h4"}
|
||||
@@ -149,6 +153,7 @@ const WorkflowHeroSection: React.FC<WorkflowHeroSectionProps> = ({
|
||||
backgroundClip: 'text',
|
||||
WebkitBackgroundClip: 'text',
|
||||
WebkitTextFillColor: 'transparent',
|
||||
lineHeight: 1.2, // Fixed line height to prevent shift
|
||||
}}
|
||||
>
|
||||
Grow Your Business Now
|
||||
@@ -220,6 +225,8 @@ const WorkflowHeroSection: React.FC<WorkflowHeroSectionProps> = ({
|
||||
background: 'linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.6), transparent)',
|
||||
animation: 'shimmer 2.5s infinite',
|
||||
zIndex: 1,
|
||||
pointerEvents: 'none', // Prevent layout impact
|
||||
willChange: 'left', // Optimize animation
|
||||
},
|
||||
'&::after': {
|
||||
content: '""',
|
||||
@@ -233,6 +240,8 @@ const WorkflowHeroSection: React.FC<WorkflowHeroSectionProps> = ({
|
||||
borderRadius: 'inherit',
|
||||
zIndex: -1,
|
||||
animation: 'borderGlow 3s ease-in-out infinite',
|
||||
pointerEvents: 'none', // Prevent layout impact
|
||||
willChange: 'background-position', // Optimize animation
|
||||
},
|
||||
'@keyframes shimmer': {
|
||||
'0%': { left: '-100%' },
|
||||
|
||||
Reference in New Issue
Block a user