diff --git a/app/chat/page.tsx b/app/chat/page.tsx index ac58f09..0a64c2a 100644 --- a/app/chat/page.tsx +++ b/app/chat/page.tsx @@ -212,7 +212,10 @@ const ChatPage = () => {
- Account + + + +
diff --git a/app/client-nav.tsx b/app/client-nav.tsx index 7136784..5afce48 100644 --- a/app/client-nav.tsx +++ b/app/client-nav.tsx @@ -1,22 +1,22 @@ "use client"; import { usePathname, useRouter } from 'next/navigation'; -import { Button } from '../src/components/ui/button'; import Image from 'next/image'; -import { useRef, useEffect } from 'react'; +import { useRef, useEffect, useState } from 'react'; +import { useTheme } from './theme-provider'; const examples = [ - { name: "Chat", href: "/chat" }, - { name: "Dashboard", href: "/dashboard" }, - { name: "Mail", href: "/mail" }, - { name: "Tree", href: "/tree" }, - { name: "Editor", href: "/editor" }, - { name: "Tables", href: "/table" }, - { name: "Meet", href: "/meet" }, - { name: "Videos", href: "/videos" }, - { name: "Music", href: "/music" }, - { name: "Templates", href: "/templates" }, - { name: "Settings", href: "/settings" }, + { name: "Chat", href: "/chat", color: "#25D366" }, // WhatsApp green + { name: "Dashboard", href: "/dashboard", color: "#6366F1" }, // Indigo + { name: "Mail", href: "/mail", color: "#FFD700" }, // Outlook yellow + { name: "Tree", href: "/tree", color: "#10B981" }, // Emerald green + { name: "Editor", href: "/editor", color: "#2563EB" }, // Word blue + { name: "Tables", href: "/table", color: "#8B5CF6" }, // Purple + { name: "Meet", href: "/meet", color: "#059669" }, // Google Meet green + { name: "Videos", href: "/videos", color: "#DC2626" }, // YouTube red + { name: "Music", href: "/music", color: "#1DB954" }, // Spotify green + { name: "Templates", href: "/templates", color: "#F59E0B" }, // Amber + { name: "Settings", href: "/settings", color: "#6B7280" }, // Gray ]; export function Nav() { @@ -24,87 +24,94 @@ export function Nav() { const router = useRouter(); const scrollContainerRef = useRef(null); const navItemsRefs = useRef<(HTMLButtonElement | null)[]>([]); + const [isLoggedIn, setIsLoggedIn] = useState(false); + const [showLoginMenu, setShowLoginMenu] = useState(false); + const [showScrollButtons, setShowScrollButtons] = useState(false); + const loginMenuRef = useRef(null); + const [showThemeMenu, setShowThemeMenu] = useState(false); + const themeMenuRef = useRef(null); + const { theme, setTheme, themes } = useTheme(); - // Enhanced URL matching to handle sub-routes const isActive = (href: string) => { if (href === '/') return pathname === href; return pathname.startsWith(href); }; + const handleLogin = () => { + setIsLoggedIn(true); + setShowLoginMenu(false); + }; + + const handleLogout = () => { + setIsLoggedIn(false); + setShowLoginMenu(false); + }; + + const checkScrollNeeded = () => { + if (scrollContainerRef.current) { + const container = scrollContainerRef.current; + const isScrollable = container.scrollWidth > container.clientWidth; + setShowScrollButtons(isScrollable); + } + }; + + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + if (loginMenuRef.current && !loginMenuRef.current.contains(event.target as Node)) { + setShowLoginMenu(false); + } + if (themeMenuRef.current && !themeMenuRef.current.contains(event.target as Node)) { + setShowThemeMenu(false); + } + }; + + document.addEventListener('mousedown', handleClickOutside); + return () => document.removeEventListener('mousedown', handleClickOutside); + }, []); + + useEffect(() => { + checkScrollNeeded(); + window.addEventListener('resize', checkScrollNeeded); + return () => window.removeEventListener('resize', checkScrollNeeded); + }, []); + useEffect(() => { - // Load GSAP from CDN const script = document.createElement('script'); script.src = 'https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js'; script.onload = () => { const gsap = window.gsap; - // Animate navigation items on mount gsap.fromTo('.nav-item', - { - opacity: 0, - y: -10, - scale: 0.9 - }, - { - opacity: 1, - y: 0, - scale: 1, - duration: 0.6, - stagger: 0.1, - ease: "back.out(1.7)" - } + { opacity: 0, y: -10, scale: 0.9 }, + { opacity: 1, y: 0, scale: 1, duration: 0.6, stagger: 0.1, ease: "back.out(1.7)" } ); - // Add hover animations - navItemsRefs.current.forEach((item, index) => { + navItemsRefs.current.forEach((item) => { if (item) { item.addEventListener('mouseenter', () => { - gsap.to(item, { - scale: 1.05, - duration: 0.3, - ease: "power2.out" - }); + gsap.to(item, { scale: 1.05, duration: 0.3, ease: "power2.out" }); }); - item.addEventListener('mouseleave', () => { - gsap.to(item, { - scale: 1, - duration: 0.3, - ease: "power2.out" - }); + gsap.to(item, { scale: 1, duration: 0.3, ease: "power2.out" }); }); - item.addEventListener('click', () => { - gsap.to(item, { - scale: 0.95, - duration: 0.1, - yoyo: true, - repeat: 1, - ease: "power2.inOut" - }); + gsap.to(item, { scale: 0.95, duration: 0.1, yoyo: true, repeat: 1, ease: "power2.inOut" }); }); } }); - // Animate logo - gsap.fromTo('.logo', - { - opacity: 0, - x: -20, - rotate: -10 - }, - { - opacity: 1, - x: 0, - rotate: 0, - duration: 0.8, - ease: "elastic.out(1, 0.5)" - } + gsap.fromTo('.theme-toggle', + { opacity: 0, x: 20, scale: 0.8 }, + { opacity: 1, x: 0, scale: 1, duration: 0.8, delay: 0.3, ease: "elastic.out(1, 0.5)" } + ); + + gsap.fromTo('.login-button', + { opacity: 0, x: 20, scale: 0.8 }, + { opacity: 1, x: 0, scale: 1, duration: 0.8, delay: 0.4, ease: "elastic.out(1, 0.5)" } ); }; document.head.appendChild(script); - return () => { if (document.head.contains(script)) { document.head.removeChild(script); @@ -112,22 +119,32 @@ export function Nav() { }; }, []); - // Smooth scroll functions for mobile const scrollLeft = () => { - if (scrollContainerRef.current) { - scrollContainerRef.current.scrollBy({ - left: -150, - behavior: 'smooth' - }); - } + scrollContainerRef.current?.scrollBy({ left: -150, behavior: 'smooth' }); }; const scrollRight = () => { - if (scrollContainerRef.current) { - scrollContainerRef.current.scrollBy({ - left: 150, - behavior: 'smooth' - }); + scrollContainerRef.current?.scrollBy({ left: 150, behavior: 'smooth' }); + }; + + const getThemeIcon = () => { + switch(theme.name) { + case 'retrowave': return '🌌'; + case 'vapordream': return '🌀'; + case 'y2kglow': return 'đŸ’ŋ'; + case 'mellowgold': return 'â˜Žī¸'; + case 'arcadeflash': return 'đŸ•šī¸'; + case 'polaroidmemories': return '📸'; + case 'midcenturymod': return 'đŸĒ‘'; + case 'grungeera': return '🎸'; + case 'discofever': return 'đŸĒŠ'; + case 'saturdaycartoons': return 'đŸ“ē'; + case 'oldhollywood': return 'đŸŽŦ'; + case 'cyberpunk': return '🤖'; + case 'seasidepostcard': return 'đŸ–ī¸'; + case 'typewriter': return 'âŒ¨ī¸'; + case 'jazzage': return '🎷'; + default: return '🎨'; } }; @@ -142,18 +159,16 @@ export function Nav() { alt="Logo" width={64} height={24} - className="logo" /> - + {showScrollButtons && ( + + )} -
+
{examples.map((example, index) => { const active = isActive(example.href); @@ -163,6 +178,7 @@ export function Nav() { ref={el => navItemsRefs.current[index] = el} onClick={() => router.push(example.href)} className={`nav-item ${active ? 'active' : ''}`} + style={{'--neon-color': example.color} as React.CSSProperties} > {example.name}
@@ -172,9 +188,66 @@ export function Nav() {
- + {showScrollButtons && ( + + )} + +
+
+ + + {showLoginMenu && ( +
+ {!isLoggedIn ? ( + + ) : ( + + )} +
+ )} +
+ +
+ + + {showThemeMenu && ( +
+ {themes.map((t) => ( + + ))} +
+ )} +
+
@@ -188,10 +261,10 @@ export function Nav() { left: 0; right: 0; z-index: 50; - background: linear-gradient(135deg, #0a0a0a 0%, #1a1a2e 50%, #16213e 100%); - border-bottom: 1px solid #333; + background: hsl(var(--background)); height: 40px; - box-shadow: 0 2px 20px rgba(0, 255, 255, 0.1); + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5); + border-bottom: 1px solid hsl(var(--border)); } .nav-inner { @@ -208,25 +281,86 @@ export function Nav() { gap: 8px; } - .logo-container { + .auth-controls { + display: flex; + align-items: center; + gap: 8px; flex-shrink: 0; - padding: 4px; - border-radius: 6px; - background: rgba(0, 255, 255, 0.1); - box-shadow: 0 0 10px rgba(0, 255, 255, 0.3); } - - .logo { - height: 20px; - width: auto; - filter: drop-shadow(0 0 5px rgba(0, 255, 255, 0.5)); + + .login-container, + .theme-container { + position: relative; + } + + .login-button, + .theme-toggle { + background: hsl(var(--accent)); + border: 1px solid hsl(var(--border)); + color: hsl(var(--accent-foreground)); + width: 32px; + height: 32px; + border-radius: 50%; + cursor: pointer; + font-size: 16px; + display: flex; + align-items: center; + justify-content: center; + transition: all 0.3s ease; + } + + .login-button:hover, + .theme-toggle:hover { + transform: scale(1.1); + box-shadow: 0 0 10px hsla(var(--primary), 0.5); + } + + .login-menu, + .theme-menu { + position: absolute; + top: calc(100% + 8px); + right: 0; + background: hsl(var(--popover)); + border: 1px solid hsl(var(--border)); + border-radius: 6px; + min-width: 120px; + z-index: 100; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2); + padding: 4px; + display: flex; + flex-direction: column; + gap: 2px; + } + + .menu-item, + .theme-menu-item { + width: 100%; + padding: 8px 12px; + background: transparent; + border: none; + color: hsl(var(--foreground)); + font-size: 13px; + cursor: pointer; + transition: all 0.2s ease; + text-align: left; + border-radius: 4px; + } + + .menu-item:hover, + .theme-menu-item:hover { + background: hsl(var(--accent)); + color: hsl(var(--accent-foreground)); + } + + .active-theme { + background: hsl(var(--primary)); + color: hsl(var(--primary-foreground)); } .scroll-btn { - display: none; - background: rgba(0, 255, 255, 0.2); - border: 1px solid rgba(0, 255, 255, 0.3); - color: #00ffff; + background: hsl(var(--accent)); + border: 1px solid hsl(var(--border)); + color: hsl(var(--accent-foreground)); width: 32px; height: 32px; border-radius: 50%; @@ -236,12 +370,14 @@ export function Nav() { transition: all 0.3s ease; flex-shrink: 0; z-index: 10; + display: flex; + align-items: center; + justify-content: center; } .scroll-btn:hover { - background: rgba(0, 255, 255, 0.3); - box-shadow: 0 0 15px rgba(0, 255, 255, 0.5); transform: scale(1.1); + box-shadow: 0 0 10px hsla(var(--primary), 0.5); } .scroll-btn:active { @@ -274,9 +410,9 @@ export function Nav() { .nav-item { position: relative; - background: rgba(255, 255, 255, 0.05); - border: 1px solid rgba(0, 255, 255, 0.2); - color: #e0e0e0; + background: hsl(var(--card)); + border: 1px solid hsl(var(--border)); + color: hsl(var(--foreground)); font-size: 13px; font-weight: 500; padding: 6px 14px; @@ -289,8 +425,8 @@ export function Nav() { text-decoration: none; white-space: nowrap; transition: all 0.3s ease; - backdrop-filter: blur(10px); overflow: hidden; + min-width: 70px; } .nav-item::before { @@ -300,7 +436,7 @@ export function Nav() { left: -100%; width: 100%; height: 100%; - background: linear-gradient(90deg, transparent, rgba(0, 255, 255, 0.2), transparent); + background: linear-gradient(90deg, transparent, rgba(var(--neon-color-rgb, 0, 255, 255), 0.2), transparent); transition: left 0.5s; } @@ -309,28 +445,21 @@ export function Nav() { } .nav-item:hover { - background: rgba(0, 255, 255, 0.1); - border-color: rgba(0, 255, 255, 0.4); - color: #00ffff; - box-shadow: 0 0 15px rgba(0, 255, 255, 0.3); - text-shadow: 0 0 8px rgba(0, 255, 255, 0.6); + border-color: var(--neon-color, hsl(var(--primary))); + color: var(--neon-color, hsl(var(--primary))); + box-shadow: 0 0 15px rgba(var(--neon-color-rgb, 0, 255, 255), 0.3); + text-shadow: 0 0 6px rgba(var(--neon-color-rgb, 0, 255, 255), 0.4); } .nav-item.active { - background: linear-gradient(135deg, rgba(0, 255, 255, 0.2), rgba(0, 200, 255, 0.3)); - border-color: #00ffff; - color: #ffffff; - box-shadow: - 0 0 20px rgba(0, 255, 255, 0.4), - inset 0 0 10px rgba(0, 255, 255, 0.1); - text-shadow: 0 0 10px rgba(0, 255, 255, 0.8); + border-color: var(--neon-color, hsl(var(--primary))); + color: var(--neon-color, hsl(var(--primary))); + box-shadow: 0 0 20px rgba(var(--neon-color-rgb, 0, 255, 255), 0.4); + text-shadow: 0 0 8px rgba(var(--neon-color-rgb, 0, 255, 255), 0.6); } .nav-item.active:hover { - background: linear-gradient(135deg, rgba(0, 255, 255, 0.3), rgba(0, 200, 255, 0.4)); - box-shadow: - 0 0 25px rgba(0, 255, 255, 0.6), - inset 0 0 15px rgba(0, 255, 255, 0.2); + box-shadow: 0 0 25px rgba(var(--neon-color-rgb, 0, 255, 255), 0.6); } .neon-glow { @@ -339,7 +468,7 @@ export function Nav() { left: -2px; right: -2px; bottom: -2px; - background: linear-gradient(45deg, transparent, rgba(0, 255, 255, 0.3), transparent); + background: linear-gradient(45deg, transparent, rgba(var(--neon-color-rgb, 0, 255, 255), 0.3), transparent); border-radius: 8px; opacity: 0; transition: opacity 0.3s ease; @@ -354,14 +483,95 @@ export function Nav() { .nav-spacer { height: 40px; } + + /* Set CSS custom properties for each neon color */ + .nav-item[style*="--neon-color: #25D366"] { + --neon-color-rgb: 37, 211, 102; + } + .nav-item[style*="--neon-color: #6366F1"] { + --neon-color-rgb: 99, 102, 241; + } + .nav-item[style*="--neon-color: #FFD700"] { + --neon-color-rgb: 255, 215, 0; + } + .nav-item[style*="--neon-color: #10B981"] { + --neon-color-rgb: 16, 185, 129; + } + .nav-item[style*="--neon-color: #2563EB"] { + --neon-color-rgb: 37, 99, 235; + } + .nav-item[style*="--neon-color: #8B5CF6"] { + --neon-color-rgb: 139, 92, 246; + } + .nav-item[style*="--neon-color: #059669"] { + --neon-color-rgb: 5, 150, 105; + } + .nav-item[style*="--neon-color: #DC2626"] { + --neon-color-rgb: 220, 38, 38; + } + .nav-item[style*="--neon-color: #1DB954"] { + --neon-color-rgb: 29, 185, 84; + } + .nav-item[style*="--neon-color: #F59E0B"] { + --neon-color-rgb: 245, 158, 11; + } + .nav-item[style*="--neon-color: #6B7280"] { + --neon-color-rgb: 107, 114, 128; + } @media (max-width: 768px) { .nav-container { - height: 36px; + height: 44px; } .nav-spacer { + height: 44px; + } + + .nav-inner { + padding: 0 12px; + } + + .nav-content { + gap: 6px; + } + + .scroll-btn { + width: 30px; + height: 30px; + font-size: 16px; + } + + .theme-toggle, .login-button { + width: 30px; + height: 30px; + font-size: 14px; + } + + .nav-item { + font-size: 13px; + padding: 8px 16px; height: 36px; + margin: 0 2px; + } + + .nav-items { + gap: 6px; + padding: 0 8px; + } + + .auth-controls { + gap: 6px; + } + } + + @media (max-width: 480px) { + .nav-container { + height: 48px; + } + + .nav-spacer { + height: 48px; } .nav-inner { @@ -373,34 +583,35 @@ export function Nav() { } .scroll-btn { - display: flex; - align-items: center; - justify-content: center; width: 28px; height: 28px; font-size: 16px; } - .logo { - height: 16px; + .theme-toggle, .login-button { + width: 28px; + height: 28px; + font-size: 12px; } .nav-item { font-size: 12px; - padding: 4px 12px; - height: 28px; + padding: 10px 14px; + height: 34px; + margin: 0 2px; + } + + .nav-items { + gap: 4px; + padding: 0 6px; + } + + .auth-controls { + gap: 4px; } } - - @media (max-width: 480px) { - .nav-container { - height: 32px; - } - - .nav-spacer { - height: 32px; - } - + + @media (max-width: 320px) { .nav-inner { padding: 0 6px; } @@ -409,20 +620,27 @@ export function Nav() { gap: 4px; } - .scroll-btn { - width: 24px; - height: 24px; - font-size: 14px; - } - - .logo { - height: 14px; - } - .nav-item { + padding: 8px 12px; + height: 32px; font-size: 11px; - padding: 3px 10px; - height: 24px; + } + + .nav-items { + gap: 3px; + padding: 0 4px; + } + + .theme-toggle, .login-button { + width: 26px; + height: 26px; + font-size: 11px; + } + + .scroll-btn { + width: 26px; + height: 26px; + font-size: 14px; } } diff --git a/app/globals.css b/app/globals.css index b5c61c9..a90f074 100644 --- a/app/globals.css +++ b/app/globals.css @@ -1,3 +1,4 @@ @tailwind base; @tailwind components; @tailwind utilities; + diff --git a/app/layout.tsx b/app/layout.tsx index ee58407..86f79b1 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,20 +1,21 @@ -import { ThemeProvider } from '@/components/ui/theme-provider'; + import { Nav } from './client-nav'; import './globals.css'; import './globals.css' // This path is correct if the file is in your src/app directory import { ReactNode } from 'react' -import ModeToggle from '@/components/ui/mode-toggle'; +import { ThemeProvider } from './theme-provider'; + export default function RootLayout({ children }: { children: ReactNode }) { return ( -