first commit
This commit is contained in:
63
front/src/context/LayoutContext.tsx
Normal file
63
front/src/context/LayoutContext.tsx
Normal file
@@ -0,0 +1,63 @@
|
||||
import React, { createContext, useContext, useState, useEffect } from 'react';
|
||||
import { getSettings } from '../api';
|
||||
import type { SiteSettings } from '../api';
|
||||
import { useToastController, Toast, ToastTitle } from '@fluentui/react-components';
|
||||
|
||||
interface LayoutContextType {
|
||||
settings: SiteSettings | null;
|
||||
isSidebarCollapsed: boolean;
|
||||
toggleSidebar: () => void;
|
||||
isDarkMode: boolean;
|
||||
toggleTheme: () => void;
|
||||
}
|
||||
|
||||
const LayoutContext = createContext<LayoutContextType | undefined>(undefined);
|
||||
|
||||
export const LayoutProvider: React.FC<{ children: React.ReactNode; toasterId: string }> = ({ children, toasterId }) => {
|
||||
const [settings, setSettings] = useState<SiteSettings | null>(null);
|
||||
const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(false);
|
||||
const [isDarkMode, setIsDarkMode] = useState(false);
|
||||
const { dispatchToast } = useToastController(toasterId);
|
||||
|
||||
useEffect(() => {
|
||||
getSettings().then((data) => {
|
||||
setSettings(data);
|
||||
if (data.favicon) {
|
||||
let link = document.querySelector("link[rel~='icon']") as HTMLLinkElement;
|
||||
if (!link) {
|
||||
link = document.createElement('link');
|
||||
link.rel = 'icon';
|
||||
document.head.appendChild(link);
|
||||
}
|
||||
link.href = data.favicon;
|
||||
}
|
||||
if (data.siteTitle) {
|
||||
document.title = data.siteTitle;
|
||||
}
|
||||
}).catch(() => {
|
||||
dispatchToast(
|
||||
<Toast>
|
||||
<ToastTitle>站点配置获取失败!</ToastTitle>
|
||||
</Toast>,
|
||||
{ intent: 'error' }
|
||||
);
|
||||
});
|
||||
}, [dispatchToast]);
|
||||
|
||||
const toggleSidebar = () => setIsSidebarCollapsed(prev => !prev);
|
||||
const toggleTheme = () => setIsDarkMode(prev => !prev);
|
||||
|
||||
return (
|
||||
<LayoutContext.Provider value={{ settings, isSidebarCollapsed, toggleSidebar, isDarkMode, toggleTheme }}>
|
||||
{children}
|
||||
</LayoutContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useLayout = () => {
|
||||
const context = useContext(LayoutContext);
|
||||
if (!context) {
|
||||
throw new Error('useLayout must be used within a LayoutProvider');
|
||||
}
|
||||
return context;
|
||||
};
|
||||
Reference in New Issue
Block a user