mirror of https://github.com/cocosolos/ixion.git
Change interfaces to types, adjust theme context
This commit is contained in:
parent
2d1a162100
commit
5d041d5e77
|
|
@ -4,8 +4,8 @@ import { BrowserRouter, Route, Routes } from 'react-router-dom';
|
|||
import AlertComponent from './components/Alert';
|
||||
import Footer from './components/Footer';
|
||||
import Header from './components/Header';
|
||||
import SearchState, { SearchStateDefaults } from './data/SearchState';
|
||||
import ServerData from './data/ServerData';
|
||||
import { SearchState, SearchStateDefaults } from './data/SearchState';
|
||||
import { ServerData } from './data/ServerData';
|
||||
import About from './pages/About';
|
||||
import Home from './pages/Home';
|
||||
import NotFound from './pages/NotFound';
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import {
|
|||
import { useRef, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { postData } from '../apiUtil';
|
||||
import ServerData from '../data/ServerData';
|
||||
import { ServerData } from '../data/ServerData';
|
||||
import { AlertResponse } from './Alert';
|
||||
|
||||
const AddServerInput = styled('div')(({ theme }) => ({
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { ToggleButton, ToggleButtonGroup } from '@mui/material';
|
||||
import ServerData from '../data/ServerData';
|
||||
import { ServerData } from '../data/ServerData';
|
||||
|
||||
const expansions = [
|
||||
<ToggleButton
|
||||
|
|
|
|||
|
|
@ -1,17 +1,15 @@
|
|||
import { Brightness4, Brightness7, QuestionMark } from '@mui/icons-material';
|
||||
import { AppBar, Box, Toolbar, Tooltip, useTheme } from '@mui/material';
|
||||
import { AppBar, Box, Toolbar, Tooltip } from '@mui/material';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import { useContext } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { ThemeContext } from '../context/ThemeContext';
|
||||
import { ThemeMode, useThemeModeContext } from '../context/ThemeContext';
|
||||
|
||||
function scrollToTop() {
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' }); // Scrolls to the top of the page smoothly
|
||||
}
|
||||
|
||||
export default function Footer() {
|
||||
const theme = useTheme();
|
||||
const { switchColorMode } = useContext(ThemeContext);
|
||||
const { themeMode, setThemeMode } = useThemeModeContext();
|
||||
|
||||
return (
|
||||
<Box className="bottom-0 w-full flex-none">
|
||||
|
|
@ -42,12 +40,14 @@ export default function Footer() {
|
|||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title="Toggle Theme" arrow disableInteractive>
|
||||
<IconButton onClick={switchColorMode}>
|
||||
{theme.palette.mode === 'dark' ? (
|
||||
<Brightness7 />
|
||||
) : (
|
||||
<Brightness4 />
|
||||
)}
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
setThemeMode((prev: ThemeMode) =>
|
||||
prev === 'light' ? 'dark' : 'light'
|
||||
);
|
||||
}}
|
||||
>
|
||||
{themeMode === 'dark' ? <Brightness7 /> : <Brightness4 />}
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ import IconButton from '@mui/material/IconButton';
|
|||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { fetchDataFromBackend } from '../apiUtil';
|
||||
import SearchState from '../data/SearchState';
|
||||
import ServerData from '../data/ServerData';
|
||||
import { SearchState } from '../data/SearchState';
|
||||
import { ServerData } from '../data/ServerData';
|
||||
import AddServer from './AddServer';
|
||||
import { AlertResponse } from './Alert';
|
||||
import SearchServers from './SearchServers';
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import {
|
|||
Typography,
|
||||
} from '@mui/material';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import SearchState from '../data/SearchState';
|
||||
import { SearchState } from '../data/SearchState';
|
||||
|
||||
export default function SearchServers({
|
||||
showSearchServer,
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ import {
|
|||
} from '@mui/material';
|
||||
import { useState } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import ServerData, {
|
||||
import {
|
||||
ServerData,
|
||||
ServerSetting,
|
||||
ServerSettingsInfo,
|
||||
} from '../data/ServerData';
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { Card, IconButton, Tooltip, Typography } from '@mui/material';
|
|||
import Modal from '@mui/material/Modal';
|
||||
import { useState } from 'react';
|
||||
import { fetchDataFromBackend } from '../apiUtil';
|
||||
import ServerData from '../data/ServerData';
|
||||
import { ServerData } from '../data/ServerData';
|
||||
import ServerSettingsDataGrid from './ServerSettingsDataGrid';
|
||||
|
||||
export default function ServerDetailsModal({ id }: { id: number }) {
|
||||
|
|
|
|||
|
|
@ -6,14 +6,14 @@ import {
|
|||
ServerSettingsInfo,
|
||||
} from '../data/ServerData';
|
||||
|
||||
interface KeyValueRow {
|
||||
type KeyValueRow = {
|
||||
id: number;
|
||||
key: string;
|
||||
rawValue: string | number | boolean;
|
||||
name: string;
|
||||
value: string | number | boolean;
|
||||
description: string;
|
||||
}
|
||||
};
|
||||
|
||||
const columns: GridColDef[] = [
|
||||
{ field: 'key', headerName: 'Key', align: 'right', flex: 4 },
|
||||
|
|
|
|||
|
|
@ -1,44 +1,47 @@
|
|||
import { useMediaQuery } from '@mui/material';
|
||||
import { createTheme, StyledEngineProvider } from '@mui/material/styles';
|
||||
import ThemeProvider from '@mui/material/styles/ThemeProvider';
|
||||
import { createContext, ReactNode, useEffect, useMemo, useState } from 'react';
|
||||
import React, {
|
||||
createContext,
|
||||
ReactNode,
|
||||
useContext,
|
||||
useEffect,
|
||||
useState,
|
||||
} from 'react';
|
||||
|
||||
type ThemeContextType = {
|
||||
switchColorMode: () => void;
|
||||
export type ThemeMode = 'dark' | 'light';
|
||||
|
||||
type ThemeModeState = {
|
||||
themeMode: ThemeMode;
|
||||
setThemeMode: React.Dispatch<React.SetStateAction<ThemeMode>>;
|
||||
};
|
||||
|
||||
type ThemeProviderProps = {
|
||||
export const ThemeModeContext = createContext<ThemeModeState | null>(null);
|
||||
|
||||
type ThemeModeContextProviderProps = {
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
export const ThemeContext = createContext<ThemeContextType>({
|
||||
switchColorMode: () => {},
|
||||
});
|
||||
|
||||
export function ThemeContextProvider({ children }: ThemeProviderProps) {
|
||||
export function ThemeContextProvider({
|
||||
children,
|
||||
}: ThemeModeContextProviderProps) {
|
||||
const rootElement = document.getElementById('root');
|
||||
const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)');
|
||||
const [mode, setMode] = useState<'light' | 'dark'>(() => {
|
||||
const manualTheme = localStorage.getItem('theme');
|
||||
if (manualTheme && (manualTheme === 'light' || manualTheme === 'dark')) {
|
||||
return manualTheme;
|
||||
const [themeMode, setThemeMode] = useState<ThemeMode>(() => {
|
||||
const manualThemeMode = localStorage.getItem('themeMode') as ThemeMode;
|
||||
if (manualThemeMode) {
|
||||
return manualThemeMode;
|
||||
}
|
||||
return prefersDarkMode ? 'dark' : 'light';
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
localStorage.setItem('theme', mode);
|
||||
}, [mode]);
|
||||
localStorage.setItem('themeMode', themeMode as ThemeMode);
|
||||
}, [themeMode]);
|
||||
|
||||
const switchColorMode = () => {
|
||||
setMode((prevMode) => (prevMode === 'light' ? 'dark' : 'light'));
|
||||
};
|
||||
|
||||
const theme = useMemo(
|
||||
() =>
|
||||
createTheme({
|
||||
const muiTheme = createTheme({
|
||||
palette: {
|
||||
mode,
|
||||
mode: themeMode,
|
||||
},
|
||||
// All `Portal`-related components need to have the the main app wrapper element as a container
|
||||
// so that they are in the subtree under the element used in the `important` option of the Tailwind's config.
|
||||
|
|
@ -64,20 +67,27 @@ export function ThemeContextProvider({ children }: ThemeProviderProps) {
|
|||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
[rootElement, mode]
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<StyledEngineProvider injectFirst>
|
||||
<ThemeContext.Provider
|
||||
<ThemeModeContext.Provider
|
||||
value={
|
||||
// eslint-disable-next-line react/jsx-no-constructed-context-values
|
||||
{ switchColorMode }
|
||||
{ themeMode, setThemeMode }
|
||||
}
|
||||
>
|
||||
<ThemeProvider theme={theme}>{children}</ThemeProvider>
|
||||
</ThemeContext.Provider>
|
||||
<ThemeProvider theme={muiTheme}>{children}</ThemeProvider>
|
||||
</ThemeModeContext.Provider>
|
||||
</StyledEngineProvider>
|
||||
);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react-refresh/only-export-components
|
||||
export function useThemeModeContext() {
|
||||
const context = useContext(ThemeModeContext);
|
||||
if (!context) {
|
||||
throw new Error('Theme context error.');
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
export default interface SearchState {
|
||||
export type SearchState = {
|
||||
name: string;
|
||||
multibox: string[] | null;
|
||||
trusts: string[] | null;
|
||||
levelSync: string[] | null;
|
||||
maxLevel: number[];
|
||||
expansions: string[] | null;
|
||||
}
|
||||
};
|
||||
|
||||
export const SearchStateDefaults: SearchState = {
|
||||
name: '',
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
import LsbDefaults from '../../../api/defaultLsbSettings.json';
|
||||
|
||||
export interface ServerSetting {
|
||||
export type ServerSetting = {
|
||||
name: string;
|
||||
description: string;
|
||||
unit?: string;
|
||||
transform?: (arg: boolean | string | number) => boolean | string | number;
|
||||
}
|
||||
};
|
||||
|
||||
export interface ServerSettings {
|
||||
export type ServerSettings = {
|
||||
[key: string]: boolean | string | number;
|
||||
}
|
||||
};
|
||||
|
||||
export default interface ServerData {
|
||||
export type ServerData = {
|
||||
name: string;
|
||||
url: string;
|
||||
location: string;
|
||||
|
|
@ -22,7 +22,7 @@ export default interface ServerData {
|
|||
active_sessions: number;
|
||||
updated: string;
|
||||
up: boolean;
|
||||
}
|
||||
};
|
||||
|
||||
export const DemoServerData: ServerData = {
|
||||
name: 'LandSandBoat Demo',
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { Box } from '@mui/material';
|
||||
import ErrorCard from '../components/ErrorCard';
|
||||
import ServerCard from '../components/ServerCard';
|
||||
import SearchState from '../data/SearchState';
|
||||
import ServerData from '../data/ServerData';
|
||||
import { SearchState } from '../data/SearchState';
|
||||
import { ServerData } from '../data/ServerData';
|
||||
|
||||
export default function Home({
|
||||
servers,
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import { AlertResponse } from '../components/Alert';
|
|||
import ErrorCard from '../components/ErrorCard';
|
||||
import ExpansionBar from '../components/ExpansionsBar';
|
||||
import ServerSettingsDataGrid from '../components/ServerSettingsDataGrid';
|
||||
import ServerData from '../data/ServerData';
|
||||
import { ServerData } from '../data/ServerData';
|
||||
import CopyImageIcon from '../images/copy-image.png';
|
||||
|
||||
export default function ServerDetails({
|
||||
|
|
|
|||
Loading…
Reference in New Issue