Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { AuthProvider } from "./contexts/AuthContext";
import { NotificationsProvider } from "./contexts/NotificationsContext";
import { ChatProvider } from "./contexts/ChatContext";
import { PaymentProvider } from "./contexts/PaymentContext";
import { ThemeProvider } from "./contexts/ThemeContext";

const SplashPage = lazy(() => import("./pages/SplashPage"));
const LoginPage = lazy(() => import("./pages/LoginPage"));
Expand All @@ -33,6 +34,7 @@ const RouteFallback: React.FC = () => (

const App: React.FC = () => {
return (
<ThemeProvider>
<AuthProvider>
<NotificationsProvider>
<PaymentProvider>
Expand Down Expand Up @@ -76,6 +78,7 @@ const App: React.FC = () => {
</PaymentProvider>
</NotificationsProvider>
</AuthProvider>
</ThemeProvider>
);
};

Expand Down
44 changes: 25 additions & 19 deletions components/layout/DashboardLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
import React from 'react';
// FIX: Use namespace import for react-router-dom to address potential module resolution issues.
import * as ReactRouterDOM from 'react-router-dom';
import { Home, CreditCard, History, Bell, User, Zap, ChevronsUpDown, LogOut, MessageSquare, Wine, Download, X } from 'lucide-react';
import { Home, CreditCard, History, Bell, User, Zap, ChevronsUpDown, LogOut, MessageSquare, Wine, Download, X, Settings } from 'lucide-react';
import { motion, AnimatePresence } from 'framer-motion';
import { useAuth } from '../../hooks/useAuth';
import { useNotifications } from '../../contexts/NotificationsContext';
import { useChat } from '../../contexts/ChatContext';
import { useTheme } from '../../contexts/ThemeContext';
import ShinyText from '../common/ShinyText';

const navItems = [
Expand All @@ -19,12 +20,14 @@ const navItems = [
];

const bottomNavItems = [
{ path: '/dashboard/settings', icon: Settings, label: 'Settings' },
{ path: '/dashboard/profile', icon: User, label: 'Profile' }
];

const NavItem: React.FC<{ item: typeof navItems[0]; isMobile: boolean }> = ({ item, isMobile }) => {
const { unreadCount: unreadNotificationsCount } = useNotifications();
const { unreadCount: unreadChatCount } = useChat();
const { isDark } = useTheme();
const isNotificationsLink = item.label === 'Notifications';
const isChatLink = item.label === 'Chat';
const badgeCount = isNotificationsLink ? unreadNotificationsCount : (isChatLink ? unreadChatCount : 0);
Expand All @@ -39,13 +42,15 @@ const NavItem: React.FC<{ item: typeof navItems[0]; isMobile: boolean }> = ({ it
{({ isActive }) => (
<motion.div
layout
className={`flex items-center justify-center gap-2 h-11 rounded-full transition-colors duration-300 ${isActive ? 'bg-white text-black px-4' : 'text-gray-400 w-11 group-hover:bg-zinc-800'
className={`flex items-center justify-center gap-2 h-11 rounded-full transition-colors duration-300 ${isActive
? (isDark ? 'bg-white text-black px-4' : 'bg-gray-900 text-white px-4')
: (isDark ? 'text-gray-400 w-11 group-hover:bg-zinc-800' : 'text-gray-500 w-11 group-hover:bg-gray-100')
}`}
>
<div className="relative">
<item.icon className="h-5 w-5 flex-shrink-0" />
{badgeCount > 0 && (
<span className={`absolute -top-1.5 -right-1.5 bg-pink-500 text-white text-[9px] font-bold min-w-[16px] h-4 px-1 rounded-full flex items-center justify-center border-2 ${isActive ? 'border-white' : 'border-[#1C1C1C]'}`}>
<span className={`absolute -top-1.5 -right-1.5 bg-pink-500 text-white text-[9px] font-bold min-w-[16px] h-4 px-1 rounded-full flex items-center justify-center border-2 ${isActive ? (isDark ? 'border-white' : 'border-gray-900') : (isDark ? 'border-[#1C1C1C]' : 'border-white')}`}>
{badgeCount > 9 ? '9+' : badgeCount}
</span>
)}
Expand Down Expand Up @@ -73,8 +78,8 @@ const NavItem: React.FC<{ item: typeof navItems[0]; isMobile: boolean }> = ({ it
to={item.path}
className={({ isActive }) =>
`flex items-center px-3 py-2.5 rounded-md transition-colors duration-200 text-sm font-medium ${isActive
? 'bg-zinc-800 text-white'
: 'text-gray-400 hover:text-white hover:bg-zinc-800/50'
? (isDark ? 'bg-zinc-800 text-white' : 'bg-gray-200 text-gray-900')
: (isDark ? 'text-gray-400 hover:text-white hover:bg-zinc-800/50' : 'text-gray-500 hover:text-gray-900 hover:bg-gray-100')
}`
}
>
Expand All @@ -93,6 +98,7 @@ const NavItem: React.FC<{ item: typeof navItems[0]; isMobile: boolean }> = ({ it
const DashboardLayout: React.FC = () => {
const location = ReactRouterDOM.useLocation();
const { profile, logout } = useAuth();
const { isDark } = useTheme();
const allNavItemsForMobile = [...navItems, ...bottomNavItems];
const [showDownloadBanner, setShowDownloadBanner] = React.useState(() => {
// Check if banner was dismissed before
Expand All @@ -101,30 +107,30 @@ const DashboardLayout: React.FC = () => {
});

return (
<div className="flex h-screen bg-black text-gray-200 font-sans">
<div className={`flex h-screen font-sans ${isDark ? 'bg-black text-gray-200' : 'bg-white text-gray-800'}`}>
{/* Sidebar for Desktop */}
<aside className="hidden md:flex w-64 flex-col p-4 bg-[#111111] border-r border-zinc-800">
<aside className={`hidden md:flex w-64 flex-col p-4 border-r ${isDark ? 'bg-[#111111] border-zinc-800' : 'bg-gray-50 border-gray-200'}`}>
<div className="flex items-center mb-6 h-10 px-2 space-x-2">
<Zap className="h-6 w-6 text-white" />
<Zap className={`h-6 w-6 ${isDark ? 'text-white' : 'text-gray-900'}`} />
<ShinyText
text="BROCODE"
className="font-bold text-xl"
style={{ fontFamily: "'Zen Dots', cursive" }}
speed={3}
color="#ffffff"
color={isDark ? "#ffffff" : "#111827"}
shineColor="#6366f1"
/>
</div>

<div className="px-2 mb-6">
<button className="w-full flex items-center justify-between p-2 rounded-lg bg-zinc-900 border border-zinc-700/80 hover:bg-zinc-800 transition-colors">
<button className={`w-full flex items-center justify-between p-2 rounded-lg border transition-colors ${isDark ? 'bg-zinc-900 border-zinc-700/80 hover:bg-zinc-800' : 'bg-white border-gray-200 hover:bg-gray-100'}`}>
<div className="flex items-center space-x-3">
<div className="w-7 h-7 rounded-full bg-indigo-600 flex items-center justify-center font-bold text-white text-sm overflow-hidden">
{profile?.profile_pic_url ? <img src={profile.profile_pic_url} alt={profile.name} className="w-full h-full object-cover" /> : profile?.name.charAt(0).toUpperCase()}
</div>
<span className="font-semibold text-white text-sm">{profile?.name}</span>
<span className={`font-semibold text-sm ${isDark ? 'text-white' : 'text-gray-900'}`}>{profile?.name}</span>
</div>
<ChevronsUpDown className="w-4 h-4 text-gray-400" />
<ChevronsUpDown className={`w-4 h-4 ${isDark ? 'text-gray-400' : 'text-gray-400'}`} />
</button>
</div>

Expand All @@ -136,7 +142,7 @@ const DashboardLayout: React.FC = () => {
{bottomNavItems.map(item => <NavItem key={item.path} item={item} isMobile={false} />)}
<button
onClick={logout}
className="w-full flex items-center px-3 py-2.5 rounded-md transition-colors duration-200 text-sm font-medium text-gray-400 hover:text-white hover:bg-zinc-800/50"
className={`w-full flex items-center px-3 py-2.5 rounded-md transition-colors duration-200 text-sm font-medium ${isDark ? 'text-gray-400 hover:text-white hover:bg-zinc-800/50' : 'text-gray-500 hover:text-gray-900 hover:bg-gray-100'}`}
>
<LogOut className="h-5 w-5 mr-3" />
<span>Logout</span>
Expand All @@ -147,28 +153,28 @@ const DashboardLayout: React.FC = () => {

{/* Main Content */}
<main className="flex-1 flex flex-col overflow-hidden">
<header className="md:hidden flex justify-between items-center p-4 bg-[#111111] border-b border-zinc-800">
<header className={`md:hidden flex justify-between items-center p-4 border-b ${isDark ? 'bg-[#111111] border-zinc-800' : 'bg-white border-gray-200'}`}>
<ShinyText
text="BROCODE"
className="font-bold text-xl"
style={{ fontFamily: "'Zen Dots', cursive" }}
speed={3}
color="#ffffff"
color={isDark ? "#ffffff" : "#111827"}
shineColor="#6366f1"
/>
<div className="flex items-center space-x-3">
<button
onClick={logout}
className="p-2 hover:bg-zinc-800 rounded-lg transition-colors"
className={`p-2 rounded-lg transition-colors ${isDark ? 'hover:bg-zinc-800' : 'hover:bg-gray-100'}`}
aria-label="Logout"
>
<LogOut className="h-5 w-5 text-gray-400 hover:text-white" />
<LogOut className={`h-5 w-5 ${isDark ? 'text-gray-400 hover:text-white' : 'text-gray-500 hover:text-gray-900'}`} />
</button>
<span className="text-sm">{profile?.name}</span>
<img src={profile?.profile_pic_url} alt="profile" className="w-8 h-8 rounded-full" />
</div>
</header>
<div className="flex-1 overflow-y-auto p-4 md:p-8 bg-[#0a0a0a] pb-28 md:pb-8">
<div className={`flex-1 overflow-y-auto p-4 md:p-8 pb-28 md:pb-8 ${isDark ? 'bg-[#0a0a0a]' : 'bg-gray-50'}`}>
<AnimatePresence mode="wait">
<motion.div
key={location.pathname}
Expand All @@ -185,7 +191,7 @@ const DashboardLayout: React.FC = () => {

{/* Bottom Nav for Mobile */}
<div className="md:hidden fixed bottom-0 left-0 right-0 p-4 z-50">
<nav className="flex justify-around items-center bg-[#1C1C1C] rounded-full h-16 shadow-lg">
<nav className={`flex justify-around items-center rounded-full h-16 shadow-lg ${isDark ? 'bg-[#1C1C1C]' : 'bg-white border border-gray-200'}`}>
{allNavItemsForMobile.map(item => <NavItem key={item.path} item={item} isMobile={true} />)}
</nav>
</div>
Expand Down
57 changes: 57 additions & 0 deletions contexts/ThemeContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React, { createContext, useState, useEffect, useContext, ReactNode } from 'react';

export type Theme = 'dark' | 'light';

interface ThemeContextType {
theme: Theme;
toggleTheme: () => void;
setTheme: (theme: Theme) => void;
isDark: boolean;
}

const ThemeContext = createContext<ThemeContextType | undefined>(undefined);

const THEME_KEY = 'brocode_theme';

export const ThemeProvider = ({ children }: { children: ReactNode }) => {
const [theme, setThemeState] = useState<Theme>(() => {
const saved = localStorage.getItem(THEME_KEY);
return (saved === 'light' || saved === 'dark') ? saved : 'dark';
});

useEffect(() => {
localStorage.setItem(THEME_KEY, theme);
const root = document.documentElement;
if (theme === 'light') {
root.classList.add('light-theme');
root.classList.remove('dark-theme');
document.body.classList.remove('bg-black', 'text-gray-200');
document.body.classList.add('bg-white', 'text-gray-800');
} else {
root.classList.add('dark-theme');
root.classList.remove('light-theme');
document.body.classList.remove('bg-white', 'text-gray-800');
document.body.classList.add('bg-black', 'text-gray-200');
}
}, [theme]);

const toggleTheme = () => {
setThemeState(prev => prev === 'dark' ? 'light' : 'dark');
};

const setTheme = (newTheme: Theme) => {
setThemeState(newTheme);
};

return (
<ThemeContext.Provider value={{ theme, toggleTheme, setTheme, isDark: theme === 'dark' }}>
{children}
</ThemeContext.Provider>
);
};

export const useTheme = () => {
const context = useContext(ThemeContext);
if (!context) throw new Error('useTheme must be used within ThemeProvider');
return context;
};
75 changes: 74 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,79 @@
.animate-star-movement-top {
animation: star-movement-top linear infinite alternate;
}

/* ===== LIGHT THEME OVERRIDES ===== */
.light-theme body {
background-color: #ffffff !important;
color: #1f2937 !important;
}

.light-theme ::-webkit-scrollbar-track {
background: #f3f4f6;
}

.light-theme ::-webkit-scrollbar-thumb {
background-color: #d1d5db;
border: 2px solid #f3f4f6;
}

.light-theme ::-webkit-scrollbar-thumb:hover {
background-color: #9ca3af;
}

/* Sidebar & nav backgrounds */
.light-theme .bg-black { background-color: #ffffff !important; }
.light-theme .bg-\[black\] { background-color: #ffffff !important; }
.light-theme .bg-\[\#111111\] { background-color: #f9fafb !important; }
.light-theme .bg-\[\#111\] { background-color: #f3f4f6 !important; }
.light-theme .bg-\[\#0a0a0a\] { background-color: #f9fafb !important; }
.light-theme .bg-\[\#1C1C1C\] { background-color: #ffffff !important; box-shadow: 0 -1px 10px rgba(0,0,0,0.08) !important; }

/* Zinc backgrounds */
.light-theme .bg-zinc-900 { background-color: #f3f4f6 !important; }
.light-theme .bg-zinc-800 { background-color: #e5e7eb !important; }
.light-theme .bg-zinc-800\/50 { background-color: rgba(229, 231, 235, 0.5) !important; }
.light-theme .bg-zinc-900\/50 { background-color: rgba(243, 244, 246, 0.5) !important; }

/* Text colors */
.light-theme .text-white { color: #111827 !important; }
.light-theme .text-gray-200 { color: #374151 !important; }
.light-theme .text-gray-400 { color: #6b7280 !important; }
.light-theme .text-zinc-400 { color: #6b7280 !important; }
.light-theme .text-zinc-500 { color: #9ca3af !important; }
.light-theme .text-zinc-600 { color: #6b7280 !important; }

/* Borders */
.light-theme .border-zinc-800 { border-color: #e5e7eb !important; }
.light-theme .border-zinc-700 { border-color: #d1d5db !important; }
.light-theme .border-zinc-700\/80 { border-color: rgba(209, 213, 219, 0.8) !important; }
.light-theme .border-white\/5 { border-color: rgba(0, 0, 0, 0.06) !important; }

/* Hover states */
.light-theme .hover\:bg-zinc-800:hover { background-color: #e5e7eb !important; }
.light-theme .hover\:bg-zinc-800\/50:hover { background-color: rgba(229, 231, 235, 0.5) !important; }
.light-theme .hover\:text-white:hover { color: #111827 !important; }
.light-theme .hover\:text-zinc-300:hover { color: #374151 !important; }

/* Active nav pill for mobile */
.light-theme .bg-white.text-black {
background-color: #111827 !important;
color: #ffffff !important;
}

/* Cards & panels */
.light-theme .bg-black\/50 { background-color: rgba(255, 255, 255, 0.7) !important; }

/* Border badges */
.light-theme .border-\[\#1C1C1C\] { border-color: #ffffff !important; }
.light-theme .border-\[\#111\] { border-color: #f3f4f6 !important; }

/* Dashed borders */
.light-theme .border-dashed.border-zinc-700 { border-color: #d1d5db !important; }
.light-theme .border-dashed.border-zinc-800 { border-color: #d1d5db !important; }

/* Group hover text */
.light-theme .group-hover\:bg-zinc-800 { background-color: #e5e7eb !important; }
Comment on lines +149 to +150
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, let's check the current state of index.html around lines 149-150
cat -n index.html | sed -n '140,160p'

Repository: fuzziecoder/Brocode-Party-Update-App

Length of output: 1100


🏁 Script executed:

# Find all usages of group-hover:bg-zinc-800 to understand the impact
rg -n "group-hover:bg-zinc-800" -g "*.{tsx,ts,jsx,js,html}" -A 2 -B 2

Repository: fuzziecoder/Brocode-Party-Update-App

Length of output: 706


🏁 Script executed:

# Also check the surrounding CSS context to understand the pattern of light-theme overrides
cat -n index.html | sed -n '79,160p'

Repository: fuzziecoder/Brocode-Party-Update-App

Length of output: 4236


Add .group:hover context to preserve hover-only styling for group-hover in light theme.

The override omits the .group:hover selector, causing group-hover:bg-zinc-800 to apply always in light theme instead of only when the parent .group is hovered. This differs from the pattern used for regular hover states (line 127).

🛠️ Suggested fix
-    .light-theme .group-hover\:bg-zinc-800 { background-color: `#e5e7eb` !important; }
+    .light-theme .group:hover .group-hover\:bg-zinc-800 { background-color: `#e5e7eb` !important; }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/* Group hover text */
.light-theme .group-hover\:bg-zinc-800 { background-color: #e5e7eb !important; }
/* Group hover text */
.light-theme .group:hover .group-hover\:bg-zinc-800 { background-color: `#e5e7eb` !important; }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@index.html` around lines 149 - 150, The .light-theme override for the
group-hover utility currently targets ".light-theme .group-hover\:bg-zinc-800"
which makes the background apply always; change the selector to include the
parent hover context (match the pattern used for hover utilities) so it targets
the group-hover rule only when the parent .group is hovered (update the selector
for the rule referencing .group-hover\:bg-zinc-800 to include ".group:hover"
before the utility class so it mirrors the regular hover selector pattern).

</style>
<script
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyC3CGsazjI6MuH2wCBO5m5AADSbahrg8yI&libraries=marker,places"
Expand Down Expand Up @@ -104,4 +177,4 @@
<script type="module" src="/index.tsx"></script>
</body>

</html>
</html>
Loading