/* Copyright (C) 2025 QuantumNous This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . For commercial licensing, please contact support@quantumnous.com */ import HeaderBar from './headerbar'; import { Layout } from '@douyinfe/semi-ui'; import SiderBar from './SiderBar'; import App from '../../App'; import FooterBar from './Footer'; import { ToastContainer } from 'react-toastify'; import React, { useContext, useEffect, useState } from 'react'; import { useIsMobile } from '../../hooks/common/useIsMobile'; import { useSidebarCollapsed } from '../../hooks/common/useSidebarCollapsed'; import { useTranslation } from 'react-i18next'; import { API, getLogo, getSystemName, showError, setStatusData, } from '../../helpers'; import { UserContext } from '../../context/User'; import { StatusContext } from '../../context/Status'; import { useLocation } from 'react-router-dom'; const { Sider, Content, Header } = Layout; const PageLayout = () => { const [, userDispatch] = useContext(UserContext); const [, statusDispatch] = useContext(StatusContext); const isMobile = useIsMobile(); const [collapsed, , setCollapsed] = useSidebarCollapsed(); const [drawerOpen, setDrawerOpen] = useState(false); const { i18n } = useTranslation(); const location = useLocation(); const cardProPages = [ '/console/channel', '/console/log', '/console/redemption', '/console/user', '/console/token', '/console/midjourney', '/console/task', '/console/models', '/pricing', ]; const shouldHideFooter = cardProPages.includes(location.pathname); const shouldInnerPadding = location.pathname.includes('/console') && !location.pathname.startsWith('/console/chat') && location.pathname !== '/console/playground'; const isConsoleRoute = location.pathname.startsWith('/console'); const showSider = isConsoleRoute && (!isMobile || drawerOpen); useEffect(() => { if (isMobile && drawerOpen && collapsed) { setCollapsed(false); } }, [isMobile, drawerOpen, collapsed, setCollapsed]); const loadUser = () => { let user = localStorage.getItem('user'); if (user) { let data = JSON.parse(user); userDispatch({ type: 'login', payload: data }); } }; const loadStatus = async () => { try { const res = await API.get('/api/status'); const { success, data } = res.data; if (success) { statusDispatch({ type: 'set', payload: data }); setStatusData(data); } else { showError('Unable to connect to server'); } } catch (error) { showError('Failed to load status'); } }; useEffect(() => { loadUser(); loadStatus().catch(console.error); let systemName = getSystemName(); if (systemName) { document.title = systemName; } let logo = getLogo(); if (logo) { let linkElement = document.querySelector("link[rel~='icon']"); if (linkElement) { linkElement.href = logo; } } const savedLang = localStorage.getItem('i18nextLng'); if (savedLang) { i18n.changeLanguage(savedLang); } }, [i18n]); return (
setDrawerOpen((prev) => !prev)} drawerOpen={drawerOpen} />
{showSider && ( { if (isMobile) setDrawerOpen(false); }} /> )} {!shouldHideFooter && ( )}
); }; export default PageLayout;