Spaces:
Sleeping
Sleeping
File size: 7,977 Bytes
471f166 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
import React, { useState, useRef, useEffect } from 'react'
import { Share2, User, MoreHorizontal, Sparkles, ChevronDown, Edit3, Pin, Archive, Trash2, Settings, LogOut, Moon, Sun, HelpCircle } from 'lucide-react'
const Header = ({ title, onOpenSidebar, isMobile, currentConversationId, onDeleteConversation, onRenameConversation, onRenameClick, onTogglePin, onToggleArchive, currentChat, onSettingsClick, onToggleTheme, darkMode, userProfile, onHelpClick }) => {
const [showMenu, setShowMenu] = useState(() => {
return sessionStorage.getItem('showHeaderMenu') === 'true'
})
const [showUserMenu, setShowUserMenu] = useState(() => {
return sessionStorage.getItem('showUserMenu') === 'true'
})
const menuRef = useRef(null)
const userMenuRef = useRef(null)
useEffect(() => {
sessionStorage.setItem('showHeaderMenu', showMenu)
}, [showMenu])
useEffect(() => {
sessionStorage.setItem('showUserMenu', showUserMenu)
}, [showUserMenu])
// Close menus when clicking outside
useEffect(() => {
const handleClickOutside = (event) => {
if (menuRef.current && !menuRef.current.contains(event.target)) {
setShowMenu(false)
}
if (userMenuRef.current && !userMenuRef.current.contains(event.target)) {
setShowUserMenu(false)
}
}
if (showMenu || showUserMenu) {
document.addEventListener('mousedown', handleClickOutside)
}
return () => document.removeEventListener('mousedown', handleClickOutside)
}, [showMenu, showUserMenu])
return (
<header className="premium-header">
<div className="header-left">
<div className="brand-wrapper">
<span className="brand-name">Pochi <span className="brand-version">4.o</span></span>
<ChevronDown size={16} className="brand-dropdown-icon" />
</div>
</div>
<div className="header-center">
<button className="upgrade-pill" id="tour-upgrade">
<Sparkles size={14} className="sparkle-icon" />
<span>Nâng cấp lên Pro</span>
</button>
</div>
<div className="header-right">
<button
className="header-action-btn help-btn"
id="tour-help-btn"
title="Hướng dẫn sử dụng"
onClick={onHelpClick}
style={{ fontFamily: "'Outfit', sans-serif", fontWeight: 600 }}
>
<HelpCircle size={18} />
<span className="btn-label" style={{ marginTop: '1px' }}>Hướng dẫn</span>
</button>
<div className="user-avatar-container" ref={userMenuRef}>
<div
className={`user-avatar-wrapper ${showUserMenu ? 'active' : ''}`}
onClick={() => setShowUserMenu(!showUserMenu)}
id="tour-profile-header"
>
<div className="user-avatar" id="tour-profile-header-avatar">
{userProfile.avatar ? (
<img src={userProfile.avatar} alt="Avatar" />
) : (
<div className="avatar-circle small">{userProfile?.name?.charAt(0) || 'U'}</div>
)}
</div>
</div>
{showUserMenu && (
<div className="context-menu user-dropdown">
<div className="user-dropdown-header">
<div className="user-info">
<span className="user-name">{userProfile.name}</span>
<span className="user-email">{userProfile.email}</span>
</div>
</div>
<div className="divider" />
<button onClick={() => { onSettingsClick('account'); setShowUserMenu(false) }}>
<User size={14} />
<span>Tài khoản</span>
<div className="shortcut-hint">
{navigator.platform.toUpperCase().indexOf('MAC') >= 0 ? '⌘I' : 'Ctrl I'}
</div>
</button>
<button onClick={() => { onSettingsClick('general'); setShowUserMenu(false) }}>
<Settings size={14} />
<span>Cài đặt</span>
<div className="shortcut-hint">
{navigator.platform.toUpperCase().indexOf('MAC') >= 0 ? '⌘X' : 'Ctrl X'}
</div>
</button>
<button onClick={() => { onToggleTheme() }}>
{darkMode ? <Sun size={14} /> : <Moon size={14} />}
<span>{darkMode ? 'Chế độ sáng' : 'Chế độ tối'}</span>
<div className="shortcut-hint">
{navigator.platform.toUpperCase().indexOf('MAC') >= 0 ? '⌘K' : 'Ctrl K'}
</div>
</button>
<div className="divider" />
<button className="danger" onClick={() => setShowUserMenu(false)}>
<LogOut size={14} /> Đăng xuất
</button>
</div>
)}
</div>
<div className="header-menu-container" ref={menuRef}>
<button
className={`header-icon-btn more-btn ${showMenu ? 'active' : ''}`}
onClick={() => setShowMenu(!showMenu)}
disabled={!currentConversationId}
id="tour-chat-features"
>
<MoreHorizontal size={20} />
</button>
{showMenu && currentConversationId && (
<div className="context-menu header-dropdown">
<button onClick={() => {
onRenameClick()
setShowMenu(false)
}}>
<Edit3 size={14} /> Đổi tên
</button>
<button onClick={() => { onTogglePin(currentConversationId); setShowMenu(false) }}>
<Pin size={14} className={currentChat?.isPinned ? 'fill-current' : ''} />
{currentChat?.isPinned ? 'Bỏ ghim' : 'Ghim'}
</button>
<button onClick={() => { onToggleArchive(currentConversationId); setShowMenu(false) }}>
<Archive size={14} />
{currentChat?.isArchived ? 'Bỏ lưu trữ' : 'Lưu trữ'}
</button>
<div className="divider" />
<button
onClick={() => { onDeleteConversation(currentConversationId); setShowMenu(false) }}
className="danger"
>
<Trash2 size={14} /> Xóa
</button>
</div>
)}
</div>
</div>
</header>
)
}
export default Header
|