From 9f13daf443cd4a9be40b5d8707edce39a6ce53f5 Mon Sep 17 00:00:00 2001 From: ajaysi Date: Sun, 14 Sep 2025 18:56:30 +0530 Subject: [PATCH] Added beta testing for user_id=1 for all requests --- .../MainDashboard/MainDashboard.tsx | 19 +- .../components/AnalyticsInsights.tsx | 256 ++++++-- .../components/AnalyzePillarChips.tsx | 1 - .../components/CompactSidebar.tsx | 605 +++++++++++------- .../components/EngagePillarChips.tsx | 1 - .../components/EnhancedTodayChip.tsx | 3 +- .../components/WorkflowHeroSection.tsx | 76 +-- 7 files changed, 631 insertions(+), 330 deletions(-) diff --git a/frontend/src/components/MainDashboard/MainDashboard.tsx b/frontend/src/components/MainDashboard/MainDashboard.tsx index 03e7c44d..6575fea2 100644 --- a/frontend/src/components/MainDashboard/MainDashboard.tsx +++ b/frontend/src/components/MainDashboard/MainDashboard.tsx @@ -2,11 +2,9 @@ import React, { useState } from 'react'; import { Box, Container, - Grid, Alert, Snackbar, - useTheme, - useMediaQuery + useTheme } from '@mui/material'; import { motion, AnimatePresence } from 'framer-motion'; import { useNavigate } from 'react-router-dom'; @@ -15,12 +13,8 @@ import AskAlwrityIcon from '../../assets/images/AskAlwrity-min.ico'; // Shared components import DashboardHeader from '../shared/DashboardHeader'; import SystemStatusIndicator from '../ContentPlanningDashboard/components/SystemStatusIndicator'; -import SearchFilter from '../shared/SearchFilter'; -import ToolCard from '../shared/ToolCard'; -import CategoryHeader from '../shared/CategoryHeader'; import LoadingSkeleton from '../shared/LoadingSkeleton'; import ErrorDisplay from '../shared/ErrorDisplay'; -import EmptyState from '../shared/EmptyState'; import ContentLifecyclePillars from './ContentLifecyclePillars'; import AnalyticsInsights from './components/AnalyticsInsights'; import ToolsModal from './components/ToolsModal'; @@ -61,7 +55,6 @@ const MainDashboard: React.FC = () => { setSelectedSubCategory, showSnackbar, hideSnackbar, - clearFilters, } = useDashboardStore(); // Workflow store hooks @@ -219,7 +212,7 @@ const MainDashboard: React.FC = () => { // Close modal if search query is too short setToolsModalOpen(false); } - }, [searchQuery, toolCategories]); + }, [searchQuery]); // Close modal and clear search const handleCloseModal = () => { @@ -232,11 +225,7 @@ const MainDashboard: React.FC = () => { } }; - const filteredCategories = getFilteredCategories( - toolCategories, - selectedCategory, - searchQuery - ); + // Note: filteredCategories removed as it's not used in the current implementation if (loading) { return ; @@ -334,6 +323,8 @@ const MainDashboard: React.FC = () => { collapsed={sidebarCollapsed} onToggleCollapse={() => setSidebarCollapsed(!sidebarCollapsed)} theme={theme} + favorites={favorites} + onToolClick={handleToolClick} /> diff --git a/frontend/src/components/MainDashboard/components/AnalyticsInsights.tsx b/frontend/src/components/MainDashboard/components/AnalyticsInsights.tsx index 21bc41cd..7438d917 100644 --- a/frontend/src/components/MainDashboard/components/AnalyticsInsights.tsx +++ b/frontend/src/components/MainDashboard/components/AnalyticsInsights.tsx @@ -13,7 +13,6 @@ import { Divider } from '@mui/material'; import { styled } from '@mui/material/styles'; -import { keyframes } from '@mui/system'; import { CheckCircle as CheckIcon, WarningAmber as WarningIcon, @@ -53,43 +52,64 @@ interface AnalyticsInsightsProps { } const ColumnCard = styled(Card)(({ theme }) => ({ - background: 'linear-gradient(180deg, rgba(255,255,255,0.14) 0%, rgba(255,255,255,0.08) 100%)', - border: '1px solid rgba(255,255,255,0.16)', - backdropFilter: 'blur(18px)', - WebkitBackdropFilter: 'blur(18px)', - borderRadius: theme.spacing(2), + background: 'linear-gradient(135deg, rgba(15, 23, 42, 0.8) 0%, rgba(30, 41, 59, 0.7) 100%)', + border: '1px solid rgba(148, 163, 184, 0.15)', + backdropFilter: 'blur(20px)', + WebkitBackdropFilter: 'blur(20px)', + borderRadius: theme.spacing(3), overflow: 'hidden', - boxShadow: '0 8px 20px rgba(0,0,0,0.28), inset 0 1px 0 rgba(255,255,255,0.22)', - transition: 'transform 0.3s ease, box-shadow 0.3s ease', + boxShadow: '0 20px 40px -12px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.05)', + transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)', + position: 'relative', + '&::before': { + content: '""', + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 0, + background: 'linear-gradient(135deg, rgba(59, 130, 246, 0.02) 0%, rgba(147, 51, 234, 0.01) 100%)', + zIndex: -1, + }, '&:hover': { - transform: 'translateY(-3px)', - boxShadow: '0 12px 28px rgba(0,0,0,0.35), inset 0 1px 0 rgba(255,255,255,0.28)' + transform: 'translateY(-4px)', + boxShadow: '0 32px 64px -12px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.08)', + border: '1px solid rgba(148, 163, 184, 0.25)', } })); -const Pill = styled('div')<{ color: string }>(() => ({ - width: 10, - height: 10, - borderRadius: 6, -})); +// Pill component removed as it's not used const GradientHeader = styled(Box)<{ gradient: string }>(({ gradient }) => ({ background: gradient, - padding: '8px 12px', + padding: '12px 16px', color: 'white', display: 'flex', alignItems: 'center', - gap: 6, + gap: 8, + position: 'relative', + '&::after': { + content: '""', + position: 'absolute', + bottom: 0, + left: 0, + right: 0, + height: '1px', + background: 'linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.3) 50%, transparent 100%)', + } })); const Badge = styled('span')(({ theme }) => ({ - background: 'rgba(255,255,255,0.15)', - border: '1px solid rgba(255,255,255,0.35)', + background: 'rgba(255,255,255,0.2)', + border: '1px solid rgba(255,255,255,0.4)', color: 'white', - borderRadius: 999, - padding: '1px 6px', + borderRadius: 12, + padding: '4px 8px', fontWeight: 700, - fontSize: '0.65rem' + fontSize: '0.7rem', + backdropFilter: 'blur(8px)', + boxShadow: '0 2px 8px rgba(0,0,0,0.2)', + textShadow: '0 1px 2px rgba(0,0,0,0.3)' })); @@ -263,20 +283,129 @@ const AnalyticsInsights: React.FC = ({ data, onActionCli }; return ( - - - - Today's Analytics Insights - + + + + + + + Today's Analytics Insights + + + + {/* Chat with Analytics Pro Button - Inline */} + + + {columns.map((col) => { const isHovered = hovered === col.key; @@ -291,27 +420,60 @@ const AnalyticsInsights: React.FC = ({ data, onActionCli {col.items.length} - - + + {visibleItems.map((insight) => ( - - + + {insight.title} - + {insight.description} - - - + + + ))} diff --git a/frontend/src/components/MainDashboard/components/AnalyzePillarChips.tsx b/frontend/src/components/MainDashboard/components/AnalyzePillarChips.tsx index 9637f971..f88895a5 100644 --- a/frontend/src/components/MainDashboard/components/AnalyzePillarChips.tsx +++ b/frontend/src/components/MainDashboard/components/AnalyzePillarChips.tsx @@ -22,7 +22,6 @@ const AnalyzePillarChips: React.FC = ({ isHovered, pillarColor }) => { - const theme = useTheme(); const navigate = useNavigate(); // Today's tasks for Analyze pillar diff --git a/frontend/src/components/MainDashboard/components/CompactSidebar.tsx b/frontend/src/components/MainDashboard/components/CompactSidebar.tsx index 2ee24726..e66d44e2 100644 --- a/frontend/src/components/MainDashboard/components/CompactSidebar.tsx +++ b/frontend/src/components/MainDashboard/components/CompactSidebar.tsx @@ -12,11 +12,11 @@ import { motion, AnimatePresence } from 'framer-motion'; import { Search, Filter, - Settings, ChevronLeft, ChevronRight, Activity, - Zap + Zap, + Star } from 'lucide-react'; // Shared components @@ -38,6 +38,8 @@ interface CompactSidebarProps { collapsed: boolean; onToggleCollapse: () => void; theme: any; + favorites?: string[]; + onToolClick?: (tool: any) => void; } // Session control for animation @@ -69,8 +71,18 @@ const CompactSidebar: React.FC = ({ onCategoryClick, collapsed, onToggleCollapse, - theme + theme, + favorites = [], + onToolClick }) => { + // State for search expansion on hover + const [isSearchExpanded, setIsSearchExpanded] = useState(false); + // State for sidebar hover expansion + const [isSidebarHovered, setIsSidebarHovered] = useState(false); + // State for favorites expansion on hover + const [isFavoritesExpanded, setIsFavoritesExpanded] = useState(false); + // Track original collapsed state for hover behavior + const [wasOriginallyCollapsed, setWasOriginallyCollapsed] = useState(false); const [isAnimating, setIsAnimating] = useState(false); const [rippleIndex, setRippleIndex] = useState(-1); const [shouldAutoExpand, setShouldAutoExpand] = useState(false); @@ -105,7 +117,7 @@ const CompactSidebar: React.FC = ({ setIsAnimating(true); markAnimationShown(); } - }, []); // Empty dependency array - only run once on mount + }, [collapsed, userHasInteracted]); // Include dependencies to avoid warning // Handle auto-expand animation useEffect(() => { @@ -157,6 +169,25 @@ const CompactSidebar: React.FC = ({ boxShadow: { duration: 2, ease: 'easeInOut' } }) }} + onMouseEnter={() => { + setIsSidebarHovered(true); + if (collapsed) { + setUserHasInteracted(true); + setWasOriginallyCollapsed(true); + // Temporarily expand the sidebar on hover + onToggleCollapse(); + } + }} + onMouseLeave={() => { + setIsSidebarHovered(false); + setIsSearchExpanded(false); + setIsFavoritesExpanded(false); + // Collapse back if it was originally collapsed + if (wasOriginallyCollapsed) { + onToggleCollapse(); + setWasOriginallyCollapsed(false); + } + }} > = ({ width: '100%', height: 'fit-content', minHeight: '400px', - background: 'linear-gradient(135deg, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0.05) 100%)', - backdropFilter: 'blur(10px)', - border: '1px solid rgba(255,255,255,0.1)', - borderRadius: 3, + background: 'linear-gradient(135deg, rgba(15, 23, 42, 0.95) 0%, rgba(30, 41, 59, 0.9) 100%)', + backdropFilter: 'blur(24px)', + border: '1px solid rgba(148, 163, 184, 0.1)', + borderRadius: 4, overflow: 'hidden', - boxShadow: '0 8px 32px rgba(0,0,0,0.1)', + boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.25), 0 0 0 1px rgba(255, 255, 255, 0.05)', + position: 'relative', + '&::before': { + content: '""', + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 0, + background: 'linear-gradient(135deg, rgba(59, 130, 246, 0.03) 0%, rgba(147, 51, 234, 0.02) 100%)', + zIndex: -1, + }, + '&:hover': { + border: '1px solid rgba(148, 163, 184, 0.2)', + boxShadow: '0 32px 64px -12px rgba(0, 0, 0, 0.35), 0 0 0 1px rgba(255, 255, 255, 0.08)', + }, }} > {/* Header */} = ({ left: 0, right: 0, height: '1px', - background: 'linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.2) 50%, transparent 100%)', + background: 'linear-gradient(90deg, transparent 0%, rgba(59, 130, 246, 0.3) 50%, transparent 100%)', } }} > @@ -270,11 +316,12 @@ const CompactSidebar: React.FC = ({ {/* Search Section */} = ({ left: 0, right: 0, height: '1px', - background: 'linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.1) 50%, transparent 100%)', + background: 'linear-gradient(90deg, transparent 0%, rgba(59, 130, 246, 0.3) 50%, transparent 100%)', + }, + '&:hover': { + border: '1px solid rgba(148, 163, 184, 0.2)', + backgroundColor: 'rgba(15, 23, 42, 0.6)', } }}> = ({ /> - - {/* Quick Stats */} - - - - Quick Stats - - - - - Total Tools + + {/* Favorites Section */} + {favorites.length > 0 && ( + <> + + + + + + Favorite Tools - - - - - Categories - - - - - - - - - {/* Category Quick Access */} - - - - Quick Access - - - {Object.entries(toolCategories).slice(0, 5).map(([categoryId, category], index) => { - const toolCount = 'tools' in category - ? category.tools.length - : Object.values(category.subCategories).reduce((sum, subCat) => sum + subCat.tools.length, 0); - const isRippling = rippleIndex === index; - - return ( - - + {favorites.slice(0, 5).map((favoriteTool, index) => ( + onToolClick && onToolClick({ name: favoriteTool })} > - { - setUserHasInteracted(true); - onCategoryClick(categoryId, category); - }} - sx={{ - backgroundColor: selectedCategory === categoryId - ? 'rgba(74, 222, 128, 0.2)' - : isRippling - ? 'rgba(74, 222, 128, 0.15)' - : 'rgba(255,255,255,0.05)', - color: selectedCategory === categoryId || isRippling ? '#4ade80' : '#ffffff', - border: selectedCategory === categoryId - ? '1px solid rgba(74, 222, 128, 0.3)' - : isRippling - ? '1px solid rgba(74, 222, 128, 0.4)' - : '1px solid rgba(255,255,255,0.1)', - cursor: 'pointer', - transition: 'all 0.2s ease-in-out', - position: 'relative', - overflow: 'hidden', - '&::before': isRippling ? { - content: '""', - position: 'absolute', - top: 0, - left: '-100%', - width: '100%', - height: '100%', - background: 'linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent)', - animation: 'shimmer 1s ease-in-out', - '@keyframes shimmer': { - '0%': { left: '-100%' }, - '100%': { left: '100%' } - } - } : {}, - '&:hover': { - backgroundColor: selectedCategory === categoryId - ? 'rgba(74, 222, 128, 0.3)' - : 'rgba(255,255,255,0.15)', - transform: 'translateY(-1px)', - boxShadow: '0 4px 12px rgba(0,0,0,0.15)', - } - }} - /> - - - ); - })} - - + + + {favoriteTool} + + + ))} + + {favorites.length > 5 && ( + + +{favorites.length - 5} more favorites + + )} + + + + )} ) : ( /* Collapsed State - Enhanced Icons with Depth */ @@ -486,53 +459,109 @@ const CompactSidebar: React.FC = ({ whileHover={{ scale: 1.1, y: -2 }} whileTap={{ scale: 0.95 }} transition={{ type: "spring", stiffness: 300, damping: 20 }} + onMouseEnter={() => { + setIsSearchExpanded(true); + setUserHasInteracted(true); + }} + onMouseLeave={() => { + setTimeout(() => setIsSearchExpanded(false), 1000); + }} > - + - - + ? '0 8px 25px rgba(74, 222, 128, 0.3), 0 0 20px rgba(74, 222, 128, 0.2), inset 0 1px 0 rgba(255,255,255,0.2)' + : '0 6px 20px rgba(0,0,0,0.15), 0 0 15px rgba(255,255,255,0.1), inset 0 1px 0 rgba(255,255,255,0.1)', + backdropFilter: 'blur(10px)', + position: 'relative', + overflow: 'hidden', + '&::before': { + content: '""', + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 0, + background: searchQuery + ? 'linear-gradient(135deg, rgba(74, 222, 128, 0.1) 0%, rgba(34, 197, 94, 0.1) 100%)' + : 'linear-gradient(135deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.02) 100%)', + borderRadius: '10px', + zIndex: -1 + }, + '&:hover': { + color: '#ffffff', + backgroundColor: searchQuery + ? 'rgba(74, 222, 128, 0.25)' + : 'rgba(255,255,255,0.15)', + boxShadow: searchQuery + ? '0 12px 35px rgba(74, 222, 128, 0.4), 0 0 30px rgba(74, 222, 128, 0.3), inset 0 1px 0 rgba(255,255,255,0.3)' + : '0 10px 30px rgba(0,0,0,0.2), 0 0 25px rgba(255,255,255,0.15), inset 0 1px 0 rgba(255,255,255,0.2)', + transform: 'translateY(-2px)' + } + }} + > + + + + {/* Expanded Search Input */} + + {isSearchExpanded && ( + + + onSearchChange(e.target.value)} + style={{ + background: 'transparent', + border: 'none', + outline: 'none', + color: 'white', + fontSize: '14px', + width: '100%', + padding: '8px 12px', + }} + autoFocus + /> + + + )} + + @@ -591,6 +620,134 @@ const CompactSidebar: React.FC = ({ + {/* Favorites Star Icon */} + + { + setIsFavoritesExpanded(true); + setUserHasInteracted(true); + }} + onMouseLeave={() => { + setTimeout(() => setIsFavoritesExpanded(false), 1000); + }} + > + + 0 ? '#fbbf24' : 'rgba(255,255,255,0.8)', + backgroundColor: favorites.length > 0 + ? 'rgba(251, 191, 36, 0.15)' + : 'rgba(255,255,255,0.08)', + border: favorites.length > 0 + ? '2px solid rgba(251, 191, 36, 0.4)' + : '2px solid rgba(255,255,255,0.15)', + borderRadius: '12px', + width: 40, + height: 40, + boxShadow: favorites.length > 0 + ? '0 8px 25px rgba(251, 191, 36, 0.3), 0 0 20px rgba(251, 191, 36, 0.2), inset 0 1px 0 rgba(255,255,255,0.2)' + : '0 6px 20px rgba(0,0,0,0.15), 0 0 15px rgba(255,255,255,0.1), inset 0 1px 0 rgba(255,255,255,0.1)', + backdropFilter: 'blur(10px)', + position: 'relative', + overflow: 'hidden', + '&::before': { + content: '""', + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 0, + background: favorites.length > 0 + ? 'linear-gradient(135deg, rgba(251, 191, 36, 0.1) 0%, rgba(245, 158, 11, 0.1) 100%)' + : 'linear-gradient(135deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.02) 100%)', + borderRadius: '10px', + zIndex: -1 + }, + '&:hover': { + color: '#ffffff', + backgroundColor: favorites.length > 0 + ? 'rgba(251, 191, 36, 0.25)' + : 'rgba(255,255,255,0.15)', + boxShadow: favorites.length > 0 + ? '0 12px 35px rgba(251, 191, 36, 0.4), 0 0 30px rgba(251, 191, 36, 0.3), inset 0 1px 0 rgba(255,255,255,0.3)' + : '0 10px 30px rgba(0,0,0,0.2), 0 0 25px rgba(255,255,255,0.15), inset 0 1px 0 rgba(255,255,255,0.2)', + transform: 'translateY(-2px)' + } + }} + > + + + + {/* Expanded Favorites List */} + + {isFavoritesExpanded && favorites.length > 0 && ( + + + + + Favorite Tools + + {favorites.map((favoriteTool, index) => ( + onToolClick && onToolClick({ name: favoriteTool })} + > + + {favoriteTool} + + + ))} + + + )} + + + + + diff --git a/frontend/src/components/MainDashboard/components/EngagePillarChips.tsx b/frontend/src/components/MainDashboard/components/EngagePillarChips.tsx index 484a01d8..0b8c8ca5 100644 --- a/frontend/src/components/MainDashboard/components/EngagePillarChips.tsx +++ b/frontend/src/components/MainDashboard/components/EngagePillarChips.tsx @@ -23,7 +23,6 @@ const EngagePillarChips: React.FC = ({ isHovered, pillarColor }) => { - const theme = useTheme(); const navigate = useNavigate(); // Today's tasks for Engage pillar diff --git a/frontend/src/components/MainDashboard/components/EnhancedTodayChip.tsx b/frontend/src/components/MainDashboard/components/EnhancedTodayChip.tsx index b151117a..ad7f1da7 100644 --- a/frontend/src/components/MainDashboard/components/EnhancedTodayChip.tsx +++ b/frontend/src/components/MainDashboard/components/EnhancedTodayChip.tsx @@ -1,7 +1,6 @@ import React, { useState, useEffect } from 'react'; import { Box, - Typography, Chip, Tooltip } from '@mui/material'; @@ -33,7 +32,7 @@ const EnhancedTodayChip: React.FC = ({ const [modalOpen, setModalOpen] = useState(false); const [shouldShake, setShouldShake] = useState(false); const [userManuallyClosed, setUserManuallyClosed] = useState(false); - const { workflowProgress, navigationState, currentWorkflow } = useWorkflowStore(); + const { currentWorkflow } = useWorkflowStore(); // Prefer live workflow tasks (to reflect updated statuses), fallback to props const liveTasks = currentWorkflow?.tasks && Array.isArray(currentWorkflow.tasks) && currentWorkflow.tasks.length > 0 diff --git a/frontend/src/components/MainDashboard/components/WorkflowHeroSection.tsx b/frontend/src/components/MainDashboard/components/WorkflowHeroSection.tsx index beb13057..b0fa02ed 100644 --- a/frontend/src/components/MainDashboard/components/WorkflowHeroSection.tsx +++ b/frontend/src/components/MainDashboard/components/WorkflowHeroSection.tsx @@ -41,7 +41,7 @@ const WorkflowHeroSection: React.FC = ({ exit={{ opacity: 0, y: -20 }} transition={{ duration: 0.6, ease: "easeOut" }} > - {/* Backdrop Overlay - Only over pillars section */} + {/* Banner Overlay - Covers task workflow area with constrained width */} = ({ left: 0, right: 0, bottom: 0, - backgroundColor: 'rgba(0, 0, 0, 0.6)', - backdropFilter: 'blur(6px)', zIndex: 10, display: 'flex', alignItems: 'center', justifyContent: 'center', borderRadius: 2, // Match the parent container's border radius + px: 2, // Add horizontal padding to constrain width }} > - {/* Hero Content */} + {/* Hero Content - Full Coverage */} = ({ animate={{ opacity: 1, scale: 1 }} transition={{ duration: 0.8, delay: 0.2 }} > - {/* Icon */} - + {/* Main Heading with Rocket */} + + + Grow Your Business Now + + = ({ > = ({ - {/* Main Heading */} - - Grow Your Business Now - - {/* Supporting Text */} - - Start your personalized content workflow and watch your digital marketing transform. - Our AI-powered system will guide you through every step of your content journey. - {/* CTA Button */} = ({ transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)', }} > - {isLoading ? 'Starting...' : '🚀 Start Your Journey'} + {isLoading ? 'Starting...' : 'Start Today\'s Tasks'}