// src/App.jsx import React, { useState, useEffect } from 'react'; import Sidebar from './components/Sidebar/Sidebar'; // import { auth, db, FieldValue } from './firebase-config.js'; // Không import trực tiếp auth, db nữa import { generateAvatarUrl } from './utils'; import eventBus from '../public/js/utils/eventBus.js'; // Import eventBus import { showModal, hideModal } from '../public/js/modal.js'; // Import modal functions function App() { const [currentUser, setCurrentUser] = useState(null); const [loadingAuth, setLoadingAuth] = useState(true); const [departments, setDepartments] = useState([]); const [loadingDepartments, setLoadingDepartments] = useState(true); const getInitialSection = () => { const hash = window.location.hash.substring(1); const validSections = ['dashboard-section', 'tasks-section', 'personnel-section', 'departments-section', 'reports-section', 'calendar-section', 'settings-section']; return validSections.includes(hash) ? hash : 'dashboard-section'; }; const [activeSection, setActiveSection] = useState(getInitialSection()); const [isMobileMenuOpen, setMobileMenuOpen] = useState(false); // Listen for auth state changes from vanilla JS (via userManager and listeners.js) useEffect(() => { const unsubscribeUser = eventBus.subscribe('userDataUpdated', (userData) => { console.log('App.jsx: Received userDataUpdated event from EventBus:', userData); setCurrentUser(userData); setLoadingAuth(false); // If user is null, show login modal if (!userData) { showModal('loginModal'); // Ensure vanilla JS also handles hiding main content etc. // Or: React handles it completely by not rendering main UI } else { hideModal('loginModal'); } }); const unsubscribeDepartments = eventBus.subscribe('departmentsDataReady', (deptsData) => { console.log('App.jsx: Received departmentsDataReady event from EventBus:', deptsData); setDepartments(deptsData); setLoadingDepartments(false); }); // Set up reactBridge functions for vanilla JS to call window.reactBridge = { updateActiveSection: (sectionId) => { console.log("App.jsx: reactBridge.updateActiveSection called with", sectionId); setActiveSection(sectionId); }, setMobileMenuOpen: (isOpen) => { console.log("App.jsx: reactBridge.setMobileMenuOpen called with", isOpen); setMobileMenuOpen(isOpen); } // userData and departmentData are now passed via EventBus, not directly via reactBridge }; console.log("App.jsx: Bridge functions attached to window.reactBridge"); return () => { unsubscribeUser(); unsubscribeDepartments(); delete window.reactBridge; // Clean up bridge on unmount }; }, []); // Sync active section with URL hash useEffect(() => { if (currentUser) { window.location.hash = activeSection; } }, [activeSection, currentUser]); // Handle hashchange from browser (back/forward) useEffect(() => { const handleHashChange = () => { const hash = window.location.hash.substring(1); if (hash && hash !== activeSection) { setActiveSection(hash); } }; window.addEventListener('hashchange', handleHashChange); return () => { window.removeEventListener('hashchange', handleHashChange); }; }, [activeSection]); const handleNavigate = (sectionId) => { setActiveSection(sectionId); // This will trigger the useEffect above to update window.location.hash // And vanillaNavigate (in listeners.js) will listen to hashchange if (window.innerWidth < 768) { // Close sidebar on mobile after navigation setMobileMenuOpen(false); } }; const handleLogout = () => { // This will be handled by the vanilla JS auth.js via the logout button in the header // userManager.js will then publish 'userLoggedOut' which App.jsx will listen to. // You can optionally add a direct call to auth.signOut() here if you want React to initiate logout. // For now, let's keep the vanilla JS button as the initiator. console.log("App.jsx: Logout button clicked, vanilla JS should handle this."); }; // Render logic if (loadingAuth || (currentUser && loadingDepartments)) { return (

Đang tải ứng dụng...

); } if (!currentUser) { // When not logged in, only render the login modal (which is part of vanilla HTML) // The main content area (main-content) will be display:none by vanilla JS. return (
{/* Content hidden or login form shown by vanilla JS */} {/*

Vui lòng đăng nhập

*/} {/* The login modal is rendered by vanilla JS, so no React component for it here */}
); } return (
{/* Main content area, controlled by vanilla JS for now, but React header can be here */}
{/* Header is part of HTML, but React can manage its logout button etc. */} {/* For now, the logout button in HTML is handled by vanilla JS */}
{/* The mobile menu button for small screens */}
{/* This logout button is part of HTML, handled by vanilla JS */} {/* */}
{/* Nội dung chính sẽ được quản lý bởi JavaScript thuần thông qua class 'active' */} {/* Chúng ta chỉ cần đảm bảo các phần tử content-section tồn tại trong index.html */} {/* Và JavaScript thuần (listeners.js) sẽ thêm/bỏ class 'active' */} {/* Không cần render lại nội dung ở đây bằng React trừ khi chuyển hoàn toàn section đó sang React */} {/* Ví dụ, bạn có thể render: {activeSection === 'dashboard-section' && } nhưng điều đó sẽ là bước tiếp theo của việc chuyển đổi từng section */}
); } export default App;