Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
5 changes: 5 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";

import SplashPage from "./pages/SplashPage";
import LoginPage from "./pages/LoginPage";
Expand All @@ -20,13 +21,15 @@ import NotificationsPage from "./pages/NotificationsPage";
import ProfilePage from "./pages/ProfilePage";
import ChatPage from "./pages/ChatPage";
import DrinksPage from "./pages/DrinksPage";
import SettingsPage from "./pages/SettingsPage";

import DashboardLayout from "./components/layout/DashboardLayout";
import ProtectedRoute from "./components/auth/ProtectedRoute";
import TargetCursor from "./components/common/TargetCursor";

const App: React.FC = () => {
return (
<ThemeProvider>
<AuthProvider>
<NotificationsProvider>
<PaymentProvider>
Expand Down Expand Up @@ -59,6 +62,7 @@ const App: React.FC = () => {
<Route path="chat" element={<ChatPage />} />
<Route path="profile" element={<ProfilePage />} />
<Route path="profile/:userId" element={<ProfilePage />} />
<Route path="settings" element={<SettingsPage />} />
</Route>

<Route path="*" element={<Navigate to="/" />} />
Expand All @@ -68,6 +72,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
Copy Markdown

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