mirror of
https://github.com/christianvidalwolf-prog/CrazeAnalytix.git
synced 2026-08-03 13:35:24 +02:00
feat: full mobile responsive optimization for Android/iPhone
- Add bottom navigation bar (6 tabs) for mobile, hidden on desktop - Compact header with smaller logo and reduced padding on mobile - Collapsible filter bar with active filter count badge on mobile - Bottom-sheet style dropdowns with overlay and larger touch targets - Fullscreen AI chat on mobile, floating window on desktop - Responsive dashboard cards with always-visible expand button - Smaller table text and touch-friendly scroll on all data grids - iPhone safe-area support and thinner scrollbars on mobile Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
fecc7264c8
commit
9895545910
@@ -652,11 +652,11 @@ const App: React.FC = () => {
|
||||
<div className="min-h-screen flex flex-col bg-background text-slate-200">
|
||||
|
||||
{/* Header */}
|
||||
<header className="bg-slate-950/90 backdrop-blur border-b border-border py-4 px-6 relative z-40 shadow-2xl">
|
||||
<header className="bg-slate-950/90 backdrop-blur border-b border-border py-2 px-3 md:py-4 md:px-6 relative z-40 shadow-2xl">
|
||||
<div className="max-w-7xl mx-auto flex justify-between items-center">
|
||||
<div className="flex items-center gap-8">
|
||||
{/* Logo Container (Horizontal Box) - Persistent User Image */}
|
||||
<div className="h-16 w-64 relative flex-shrink-0">
|
||||
<div className="flex items-center gap-3 md:gap-8">
|
||||
{/* Logo Container - Smaller on mobile */}
|
||||
<div className="h-10 w-32 md:h-16 md:w-64 relative flex-shrink-0">
|
||||
<CrazeLogo />
|
||||
</div>
|
||||
|
||||
@@ -677,63 +677,62 @@ const App: React.FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-6">
|
||||
<div className="flex items-center gap-3 md:gap-6">
|
||||
{/* Force Sync Action */}
|
||||
<button
|
||||
onClick={() => { handleDataFetch(); handleAdsFetch(); handleTrafficFetch(); handleVendorStockFetch(); handleBuyBoxFetch(); }}
|
||||
disabled={syncing}
|
||||
className={`flex items-center gap-2 px-4 py-2 rounded-xl text-sm font-black uppercase tracking-widest transition-all
|
||||
className={`flex items-center gap-2 px-3 py-1.5 md:px-4 md:py-2 rounded-xl text-sm font-black uppercase tracking-widest transition-all
|
||||
${syncing
|
||||
? 'bg-indigo-500/20 text-indigo-400 border border-indigo-500/30'
|
||||
: 'bg-slate-900 text-slate-300 border border-border hover:border-indigo-500/50 hover:text-white shadow-lg active:scale-95'}`}
|
||||
>
|
||||
<RefreshIcon className={`w-4 h-4 ${syncing ? 'animate-spin' : ''}`} />
|
||||
<span>{syncing ? 'Syncing...' : 'Sync Now'}</span>
|
||||
<span className="hidden sm:inline">{syncing ? 'Syncing...' : 'Sync Now'}</span>
|
||||
</button>
|
||||
{/* View Switcher is the priority now */}
|
||||
{/* View Switcher */}
|
||||
<div className="flex bg-slate-900 rounded-lg p-1 border border-border">
|
||||
{/* View Switcher - Hidden on mobile (shown in bottom nav instead) */}
|
||||
<div className="hidden md:flex bg-slate-900 rounded-lg p-1 border border-border">
|
||||
<button
|
||||
onClick={() => setView('dashboard')}
|
||||
className={`flex items-center gap-2 px-3 py-2 rounded-md text-sm font-medium transition-all
|
||||
${view === 'dashboard' ? 'bg-slate-800 text-white shadow-sm ring-1 ring-white/10' : 'text-slate-400 hover:text-white hover:bg-slate-800/50'}`}
|
||||
>
|
||||
<ChartIcon /> <span className="hidden sm:inline">Dashboard</span>
|
||||
<ChartIcon /> <span className="hidden lg:inline">Dashboard</span>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setView('table')}
|
||||
className={`flex items-center gap-2 px-3 py-2 rounded-md text-sm font-medium transition-all
|
||||
${view === 'table' ? 'bg-slate-800 text-white shadow-sm ring-1 ring-white/10' : 'text-slate-400 hover:text-white hover:bg-slate-800/50'}`}
|
||||
>
|
||||
<TableIcon /> <span className="hidden sm:inline">Grid</span>
|
||||
<TableIcon /> <span className="hidden lg:inline">Grid</span>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setView('weekly')}
|
||||
className={`flex items-center gap-2 px-3 py-2 rounded-md text-sm font-medium transition-all
|
||||
${view === 'weekly' ? 'bg-slate-800 text-white shadow-sm ring-1 ring-white/10' : 'text-slate-400 hover:text-white hover:bg-slate-800/50'}`}
|
||||
>
|
||||
<TrendingIcon /> <span className="hidden sm:inline">Weekly Sales</span>
|
||||
<TrendingIcon /> <span className="hidden lg:inline">Weekly Sales</span>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setView('movers')}
|
||||
className={`flex items-center gap-2 px-3 py-2 rounded-md text-sm font-medium transition-all
|
||||
${view === 'movers' ? 'bg-slate-800 text-white shadow-sm ring-1 ring-white/10' : 'text-slate-400 hover:text-white hover:bg-slate-800/50'}`}
|
||||
>
|
||||
<TrendingIcon /> <span className="hidden sm:inline">Movers</span>
|
||||
<TrendingIcon /> <span className="hidden lg:inline">Movers</span>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setView('ads')}
|
||||
className={`flex items-center gap-2 px-3 py-2 rounded-md text-sm font-medium transition-all
|
||||
${view === 'ads' ? 'bg-slate-800 text-white shadow-sm ring-1 ring-white/10' : 'text-slate-400 hover:text-white hover:bg-slate-800/50'}`}
|
||||
>
|
||||
<MegaphoneIcon /> <span className="hidden sm:inline">Ads</span>
|
||||
<MegaphoneIcon /> <span className="hidden lg:inline">Ads</span>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setView('forecast')}
|
||||
className={`flex items-center gap-2 px-3 py-2 rounded-md text-sm font-medium transition-all
|
||||
${view === 'forecast' ? 'bg-slate-800 text-white shadow-sm ring-1 ring-white/10' : 'text-slate-400 hover:text-white hover:bg-slate-800/50'}`}
|
||||
>
|
||||
<ChartIcon /> <span className="hidden sm:inline">Fc 26</span>
|
||||
<ChartIcon /> <span className="hidden lg:inline">Fc 26</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -850,6 +849,30 @@ const App: React.FC = () => {
|
||||
{/* Chat Assistant */}
|
||||
<AIChat onSendMessage={handleAskGemini} isOpen={isChatOpen} setIsOpen={setIsChatOpen} />
|
||||
|
||||
{/* Mobile Bottom Navigation */}
|
||||
<nav className="fixed bottom-0 left-0 right-0 z-50 bg-slate-950/95 backdrop-blur border-t border-border md:hidden pb-safe">
|
||||
<div className="grid grid-cols-6 gap-0">
|
||||
{([
|
||||
{ key: 'dashboard' as const, icon: <ChartIcon />, label: 'Home' },
|
||||
{ key: 'table' as const, icon: <TableIcon />, label: 'Grid' },
|
||||
{ key: 'weekly' as const, icon: <TrendingIcon />, label: 'Weekly' },
|
||||
{ key: 'movers' as const, icon: <TrendingIcon />, label: 'Movers' },
|
||||
{ key: 'ads' as const, icon: <MegaphoneIcon />, label: 'Ads' },
|
||||
{ key: 'forecast' as const, icon: <ChartIcon />, label: 'Fc 26' },
|
||||
]).map(({ key, icon, label }) => (
|
||||
<button
|
||||
key={key}
|
||||
onClick={() => setView(key)}
|
||||
className={`flex flex-col items-center justify-center py-2 gap-0.5 transition-colors
|
||||
${view === key ? 'text-primary' : 'text-slate-500 active:text-slate-300'}`}
|
||||
>
|
||||
{icon}
|
||||
<span className="text-[9px] font-bold uppercase tracking-wider">{label}</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
{/* DATA MODAL */}
|
||||
{
|
||||
isDataModalOpen && (
|
||||
|
||||
Reference in New Issue
Block a user