mirror of https://github.com/cocosolos/ixion.git
Add more filters
This commit is contained in:
parent
814092a9f0
commit
52908764ed
|
|
@ -3,7 +3,7 @@ import { useState } from 'react';
|
|||
import { BrowserRouter, Route, Routes } from 'react-router-dom';
|
||||
import AlertComponent from './components/Alert';
|
||||
import Footer from './components/Footer';
|
||||
import Header from './components/Header';
|
||||
import Header from './components/Header/Header';
|
||||
import { SearchState, SearchStateDefaults } from './data/SearchState';
|
||||
import { ServerData } from './data/ServerData';
|
||||
import About from './pages/About';
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ import {
|
|||
} from '@mui/material';
|
||||
import { useRef, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { postData } from '../apiUtil';
|
||||
import { useLoadingContext } from '../context/LoadingContext';
|
||||
import { ServerData } from '../data/ServerData';
|
||||
import { postData } from '../../apiUtil';
|
||||
import { useLoadingContext } from '../../context/LoadingContext';
|
||||
import { ServerData } from '../../data/ServerData';
|
||||
|
||||
const AddServerInput = styled('div')(({ theme }) => ({
|
||||
position: 'relative',
|
||||
|
|
@ -10,10 +10,11 @@ import {
|
|||
import IconButton from '@mui/material/IconButton';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { fetchDataFromBackend } from '../apiUtil';
|
||||
import { useLoadingContext } from '../context/LoadingContext';
|
||||
import { SearchState } from '../data/SearchState';
|
||||
import { ServerData } from '../data/ServerData';
|
||||
import { fetchDataFromBackend } from '../../apiUtil';
|
||||
import { useLoadingContext } from '../../context/LoadingContext';
|
||||
import { useThemeModeContext } from '../../context/ThemeContext';
|
||||
import { SearchState } from '../../data/SearchState';
|
||||
import { ServerData } from '../../data/ServerData';
|
||||
import AddServer from './AddServer';
|
||||
import SearchServers from './SearchServers';
|
||||
|
||||
|
|
@ -30,6 +31,7 @@ export default function Header({
|
|||
searchState,
|
||||
setSearchState,
|
||||
}: HeaderProps) {
|
||||
const { themeMode } = useThemeModeContext();
|
||||
const { progress, setProgress, showAlert } = useLoadingContext();
|
||||
const [showSearchServer, setShowSearchServer] = useState(false);
|
||||
const toggleShowSearchServer = () => {
|
||||
|
|
@ -67,7 +69,7 @@ export default function Header({
|
|||
|
||||
return (
|
||||
<Box>
|
||||
<AppBar position="static">
|
||||
<AppBar position="static" elevation={themeMode === 'light' ? 8 : 3}>
|
||||
<Toolbar className="min-h-min py-1">
|
||||
<Typography
|
||||
component={Link}
|
||||
|
|
@ -0,0 +1,640 @@
|
|||
import { RestartAlt } from '@mui/icons-material';
|
||||
import {
|
||||
Box,
|
||||
Container,
|
||||
Grid,
|
||||
IconButton,
|
||||
Input,
|
||||
Slider,
|
||||
TextField,
|
||||
ToggleButton,
|
||||
ToggleButtonGroup,
|
||||
Tooltip,
|
||||
Typography,
|
||||
} from '@mui/material';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { SearchState, SearchStateDefaults } from '../../data/SearchState';
|
||||
|
||||
type SearchServersProps = {
|
||||
showSearchServer: boolean;
|
||||
searchState: SearchState;
|
||||
setSearchState: React.Dispatch<React.SetStateAction<SearchState>>;
|
||||
};
|
||||
|
||||
export default function SearchServers({
|
||||
showSearchServer,
|
||||
searchState,
|
||||
setSearchState,
|
||||
}: SearchServersProps) {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const [contentHeight, setContentHeight] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
if (showSearchServer && containerRef.current) {
|
||||
setContentHeight(containerRef.current.scrollHeight);
|
||||
} else {
|
||||
setContentHeight(0);
|
||||
}
|
||||
}, [showSearchServer]);
|
||||
|
||||
const handleChange = (
|
||||
name: string,
|
||||
value: string | string[] | number | number[],
|
||||
activeThumb?: number
|
||||
) => {
|
||||
let newValue = value;
|
||||
if (name === 'maxLevel') {
|
||||
if (
|
||||
!Array.isArray(value) ||
|
||||
!value.every((item) => typeof item === 'number')
|
||||
) {
|
||||
return;
|
||||
}
|
||||
newValue = [
|
||||
activeThumb === 0
|
||||
? Math.min((newValue as number[])[0], searchState.maxLevel[1])
|
||||
: searchState.maxLevel[0],
|
||||
activeThumb === 0
|
||||
? searchState.maxLevel[1]
|
||||
: Math.max((newValue as number[])[1], searchState.maxLevel[0]),
|
||||
];
|
||||
}
|
||||
setSearchState({ ...searchState, [name]: newValue });
|
||||
};
|
||||
|
||||
const handleSearchExpansions = (
|
||||
_event: React.MouseEvent<HTMLElement>,
|
||||
newSearchExpansions: string[]
|
||||
) => {
|
||||
if (newSearchExpansions.length === 0) {
|
||||
setSearchState({ ...searchState, expansions: null });
|
||||
} else if (
|
||||
searchState.expansions &&
|
||||
searchState.expansions.includes('none') &&
|
||||
newSearchExpansions.length > 1
|
||||
) {
|
||||
setSearchState({
|
||||
...searchState,
|
||||
expansions: newSearchExpansions.filter((item) => item !== 'none'),
|
||||
});
|
||||
} else if (
|
||||
searchState.expansions &&
|
||||
!searchState.expansions.includes('none') &&
|
||||
newSearchExpansions.includes('none')
|
||||
) {
|
||||
setSearchState({ ...searchState, expansions: ['none'] });
|
||||
} else {
|
||||
setSearchState({ ...searchState, expansions: newSearchExpansions });
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Container
|
||||
ref={containerRef}
|
||||
className="overflow-hidden"
|
||||
sx={{
|
||||
transition: 'all 0.3s ease',
|
||||
maxHeight: showSearchServer ? contentHeight : 0,
|
||||
borderBottom: showSearchServer
|
||||
? (theme) =>
|
||||
theme.palette.mode === 'dark'
|
||||
? '1px solid rgba(255, 255, 255, .12)'
|
||||
: '1px solid rgba(0, 0, 0, .12)'
|
||||
: 'none',
|
||||
backgroundColor: (theme) =>
|
||||
theme.palette.mode === 'dark'
|
||||
? 'rgba(255, 255, 255, .06)'
|
||||
: 'rgba(0, 0, 0, .06)',
|
||||
}}
|
||||
>
|
||||
<Grid container spacing={2} className="py-2">
|
||||
{/* Name */}
|
||||
<Grid item xs={12}>
|
||||
<TextField
|
||||
value={searchState.name}
|
||||
onChange={(event) => {
|
||||
handleChange('name', event.target.value);
|
||||
}}
|
||||
variant="standard"
|
||||
autoComplete="false"
|
||||
fullWidth
|
||||
label="Name"
|
||||
size="small"
|
||||
className="pb-2"
|
||||
/>
|
||||
</Grid>
|
||||
{/* Max Level */}
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
className="pt-0"
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
alignItems="center"
|
||||
>
|
||||
<Typography id="max-level" variant="caption">
|
||||
Max Level
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} className="flex pt-0">
|
||||
<Input
|
||||
value={searchState.maxLevel[0]}
|
||||
size="small"
|
||||
onChange={(event) => {
|
||||
let value = parseInt(event.target.value, 10);
|
||||
if (Number.isNaN(value) || value < 1) {
|
||||
value = 1;
|
||||
} else if (value > 99) {
|
||||
value = 99;
|
||||
}
|
||||
handleChange('maxLevel', [value, searchState.maxLevel[1]], 0);
|
||||
}}
|
||||
// onBlur={handleBlur}
|
||||
inputProps={{
|
||||
name: 'max-level-min',
|
||||
step: 1,
|
||||
min: 1,
|
||||
max: 99,
|
||||
type: 'number',
|
||||
'aria-labelledby': 'max-level',
|
||||
}}
|
||||
/>
|
||||
<Slider
|
||||
aria-labelledby="max-level"
|
||||
value={searchState.maxLevel}
|
||||
onChange={(_event, value, activeThumb) => {
|
||||
handleChange('maxLevel', value, activeThumb);
|
||||
}}
|
||||
valueLabelDisplay="auto"
|
||||
disableSwap
|
||||
className="mx-4"
|
||||
size="small"
|
||||
min={1}
|
||||
max={99}
|
||||
/>
|
||||
<Input
|
||||
value={searchState.maxLevel[1]}
|
||||
size="small"
|
||||
onChange={(event) => {
|
||||
let value = parseInt(event.target.value, 10);
|
||||
if (Number.isNaN(value) || value < 1) {
|
||||
value = 1;
|
||||
} else if (value > 99) {
|
||||
value = 99;
|
||||
}
|
||||
handleChange('maxLevel', [searchState.maxLevel[0], value], 1);
|
||||
}}
|
||||
// onBlur={handleBlur}
|
||||
inputProps={{
|
||||
name: 'max-level-max',
|
||||
step: 1,
|
||||
min: 1,
|
||||
max: 99,
|
||||
type: 'number',
|
||||
'aria-labelledby': 'max-level',
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
{/* Expansion */}
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
alignItems="center"
|
||||
>
|
||||
<Tooltip
|
||||
title="Enabled expansions, exact match."
|
||||
arrow
|
||||
disableInteractive
|
||||
placement="top"
|
||||
>
|
||||
<Typography id="expansions-button-group" variant="caption">
|
||||
Expansions
|
||||
</Typography>
|
||||
</Tooltip>
|
||||
<ToggleButtonGroup
|
||||
value={searchState.expansions}
|
||||
onChange={handleSearchExpansions}
|
||||
size="small"
|
||||
aria-labelledby="expansions-button-group"
|
||||
sx={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<ToggleButton
|
||||
key="none"
|
||||
value="none"
|
||||
aria-label="none-enabled"
|
||||
className="py-0"
|
||||
sx={{ width: '20%' }}
|
||||
>
|
||||
None
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
key="rotz"
|
||||
value="rotz"
|
||||
aria-label="rotz-enabled"
|
||||
className="py-0"
|
||||
sx={{ width: '20%' }}
|
||||
>
|
||||
RotZ
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
key="cop"
|
||||
value="cop"
|
||||
aria-label="cop-enabled"
|
||||
className="py-0"
|
||||
sx={{ width: '20%' }}
|
||||
>
|
||||
CoP
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
key="toau"
|
||||
value="toau"
|
||||
aria-label="toau-enabled"
|
||||
className="py-0"
|
||||
sx={{ width: '20%' }}
|
||||
>
|
||||
ToAU
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
key="wotg"
|
||||
value="wotg"
|
||||
aria-label="wotg-enabled"
|
||||
className="py-0"
|
||||
sx={{ width: '20%' }}
|
||||
>
|
||||
WotG
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
key="soa"
|
||||
value="soa"
|
||||
aria-label="soa-enabled"
|
||||
className="py-0"
|
||||
sx={{ width: '20%' }}
|
||||
>
|
||||
SoA
|
||||
</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</Grid>
|
||||
{/* Multiboxing */}
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
alignItems="center"
|
||||
>
|
||||
<Typography id="multibox-button-group" variant="caption">
|
||||
Multiboxing
|
||||
</Typography>
|
||||
<ToggleButtonGroup
|
||||
value={searchState.multibox}
|
||||
onChange={(_event, value) => {
|
||||
handleChange('multibox', value);
|
||||
}}
|
||||
size="small"
|
||||
aria-labelledby="multibox-button-group"
|
||||
sx={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
}}
|
||||
exclusive
|
||||
>
|
||||
<ToggleButton
|
||||
value="none"
|
||||
aria-label="no-multiboxing"
|
||||
className="py-0"
|
||||
sx={{ width: '33.33%' }}
|
||||
>
|
||||
None
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
value="limited"
|
||||
aria-label="limited-multiboxing"
|
||||
className="py-0"
|
||||
sx={{ width: '33.33%' }}
|
||||
>
|
||||
Limited
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
value="unlimited"
|
||||
aria-label="unlimited-multiboxing"
|
||||
className="py-0"
|
||||
sx={{ width: '33.33%' }}
|
||||
>
|
||||
Unlimited
|
||||
</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</Grid>
|
||||
{/* Trusts */}
|
||||
<Grid
|
||||
item
|
||||
xs={6}
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
alignItems="center"
|
||||
>
|
||||
<Typography id="trust-button-group" variant="caption">
|
||||
Trusts
|
||||
</Typography>
|
||||
<ToggleButtonGroup
|
||||
value={searchState.trusts}
|
||||
onChange={(_event, value) => {
|
||||
handleChange('trusts', value);
|
||||
}}
|
||||
size="small"
|
||||
aria-labelledby="trust-button-group"
|
||||
exclusive
|
||||
sx={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<ToggleButton
|
||||
value="disabled"
|
||||
aria-label="trust-disabled"
|
||||
className="py-0"
|
||||
sx={{ width: '50%' }}
|
||||
>
|
||||
Disabled
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
value="enabled"
|
||||
aria-label="trust-enabled"
|
||||
className="py-0"
|
||||
sx={{ width: '50%' }}
|
||||
>
|
||||
Enabled
|
||||
</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</Grid>
|
||||
{/* Level Sync */}
|
||||
<Grid
|
||||
item
|
||||
xs={6}
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
alignItems="center"
|
||||
>
|
||||
<Typography id="level-sync-button-group" variant="caption">
|
||||
Level Sync
|
||||
</Typography>
|
||||
<ToggleButtonGroup
|
||||
value={searchState.levelSync}
|
||||
onChange={(_event, value) => {
|
||||
handleChange('levelSync', value);
|
||||
}}
|
||||
size="small"
|
||||
aria-labelledby="level-sync-button-group"
|
||||
exclusive
|
||||
sx={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<ToggleButton
|
||||
value="disabled"
|
||||
aria-label="level-sync-disabled"
|
||||
className="py-0"
|
||||
sx={{ width: '50%' }}
|
||||
>
|
||||
Disabled
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
value="enabled"
|
||||
aria-label="level-sync-enabled"
|
||||
className="py-0"
|
||||
sx={{ width: '50%' }}
|
||||
>
|
||||
Enabled
|
||||
</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</Grid>
|
||||
{/* Home Point Teleport */}
|
||||
<Grid
|
||||
item
|
||||
xs={6}
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
alignItems="center"
|
||||
>
|
||||
<Typography id="home-point-button-group" variant="caption">
|
||||
Home Point Teleport
|
||||
</Typography>
|
||||
<ToggleButtonGroup
|
||||
value={searchState.homePoint}
|
||||
onChange={(_event, value) => {
|
||||
handleChange('homePoint', value);
|
||||
}}
|
||||
size="small"
|
||||
aria-labelledby="home-point-button-group"
|
||||
exclusive
|
||||
sx={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<ToggleButton
|
||||
value="disabled"
|
||||
aria-label="home-point-disabled"
|
||||
className="py-0"
|
||||
sx={{ width: '50%' }}
|
||||
>
|
||||
Disabled
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
value="enabled"
|
||||
aria-label="home-point-enabled"
|
||||
className="py-0"
|
||||
sx={{ width: '50%' }}
|
||||
>
|
||||
Enabled
|
||||
</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</Grid>
|
||||
{/* Survival Guide Teleport */}
|
||||
<Grid
|
||||
item
|
||||
xs={6}
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
alignItems="center"
|
||||
>
|
||||
<Typography id="survival-guide-button-group" variant="caption">
|
||||
Survival Guides
|
||||
</Typography>
|
||||
<ToggleButtonGroup
|
||||
value={searchState.survivalGuide}
|
||||
onChange={(_event, value) => {
|
||||
handleChange('survivalGuide', value);
|
||||
}}
|
||||
size="small"
|
||||
aria-labelledby="survival-guide-button-group"
|
||||
exclusive
|
||||
sx={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<ToggleButton
|
||||
value="disabled"
|
||||
aria-label="survival-guide-disabled"
|
||||
className="py-0"
|
||||
sx={{ width: '50%' }}
|
||||
>
|
||||
Disabled
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
value="enabled"
|
||||
aria-label="survival-guide-enabled"
|
||||
className="py-0"
|
||||
sx={{ width: '50%' }}
|
||||
>
|
||||
Enabled
|
||||
</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</Grid>
|
||||
{/* Records of Eminence */}
|
||||
<Grid
|
||||
item
|
||||
xs={4}
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
alignItems="center"
|
||||
>
|
||||
<Typography id="roe-button-group" variant="caption">
|
||||
Records of Eminence
|
||||
</Typography>
|
||||
<ToggleButtonGroup
|
||||
value={searchState.recordsOfEminence}
|
||||
onChange={(_event, value) => {
|
||||
handleChange('recordsOfEminence', value);
|
||||
}}
|
||||
size="small"
|
||||
aria-labelledby="records-of-eminence-button-group"
|
||||
exclusive
|
||||
sx={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<ToggleButton
|
||||
value="disabled"
|
||||
aria-label="records-of-eminence-disabled"
|
||||
className="py-0"
|
||||
sx={{ width: '50%' }}
|
||||
>
|
||||
Disabled
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
value="enabled"
|
||||
aria-label="records-of-eminence-enabled"
|
||||
className="py-0"
|
||||
sx={{ width: '50%' }}
|
||||
>
|
||||
Enabled
|
||||
</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</Grid>
|
||||
{/* Fields of Valor */}
|
||||
<Grid
|
||||
item
|
||||
xs={4}
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
alignItems="center"
|
||||
>
|
||||
<Typography id="fields-of-valor-button-group" variant="caption">
|
||||
Fields of Valor
|
||||
</Typography>
|
||||
<ToggleButtonGroup
|
||||
value={searchState.fieldsOfValor}
|
||||
onChange={(_event, value) => {
|
||||
handleChange('fieldsOfValor', value);
|
||||
}}
|
||||
size="small"
|
||||
aria-labelledby="fields-of-valor-button-group"
|
||||
exclusive
|
||||
sx={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<ToggleButton
|
||||
value="disabled"
|
||||
aria-label="fields-of-valor-disabled"
|
||||
className="py-0"
|
||||
sx={{ width: '50%' }}
|
||||
>
|
||||
Disabled
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
value="enabled"
|
||||
aria-label="fields-of-valor-enabled"
|
||||
className="py-0"
|
||||
sx={{ width: '50%' }}
|
||||
>
|
||||
Enabled
|
||||
</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</Grid>
|
||||
{/* Grounds of Valor */}
|
||||
<Grid
|
||||
item
|
||||
xs={4}
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
alignItems="center"
|
||||
>
|
||||
<Typography id="grounds-of-valor-button-group" variant="caption">
|
||||
Grounds of Valor
|
||||
</Typography>
|
||||
<ToggleButtonGroup
|
||||
value={searchState.groundsOfValor}
|
||||
onChange={(_event, value) => {
|
||||
handleChange('groundsOfValor', value);
|
||||
}}
|
||||
size="small"
|
||||
aria-labelledby="grounds-of-valor-button-group"
|
||||
exclusive
|
||||
sx={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<ToggleButton
|
||||
value="disabled"
|
||||
aria-label="grounds-of-valor-disabled"
|
||||
className="py-0"
|
||||
sx={{ width: '50%' }}
|
||||
>
|
||||
Disabled
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
value="enabled"
|
||||
aria-label="grounds-of-valor-enabled"
|
||||
className="py-0"
|
||||
sx={{ width: '50%' }}
|
||||
>
|
||||
Enabled
|
||||
</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</Grid>
|
||||
<Box className="flex min-w-full justify-end pt-2">
|
||||
<Tooltip title="Reset filters." arrow disableInteractive>
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
setSearchState(SearchStateDefaults);
|
||||
}}
|
||||
>
|
||||
<RestartAlt />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
</Grid>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,452 +0,0 @@
|
|||
import {
|
||||
Container,
|
||||
Divider,
|
||||
Grid,
|
||||
Input,
|
||||
Slider,
|
||||
TextField,
|
||||
ToggleButton,
|
||||
ToggleButtonGroup,
|
||||
Tooltip,
|
||||
Typography,
|
||||
} from '@mui/material';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { SearchState } from '../data/SearchState';
|
||||
|
||||
type SearchServersProps = {
|
||||
showSearchServer: boolean;
|
||||
searchState: SearchState;
|
||||
setSearchState: React.Dispatch<React.SetStateAction<SearchState>>;
|
||||
};
|
||||
|
||||
export default function SearchServers({
|
||||
showSearchServer,
|
||||
searchState,
|
||||
setSearchState,
|
||||
}: SearchServersProps) {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const [contentHeight, setContentHeight] = useState(0);
|
||||
const minDistance = 0;
|
||||
|
||||
useEffect(() => {
|
||||
if (showSearchServer && containerRef.current) {
|
||||
setContentHeight(containerRef.current.scrollHeight);
|
||||
} else {
|
||||
setContentHeight(0);
|
||||
}
|
||||
}, [showSearchServer]);
|
||||
|
||||
const handleSearchName = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setSearchState({ ...searchState, name: event.target.value });
|
||||
};
|
||||
|
||||
const handleSearchMultibox = (
|
||||
_event: React.MouseEvent<HTMLElement>,
|
||||
newSearchMultibox: string[]
|
||||
) => {
|
||||
setSearchState({ ...searchState, multibox: newSearchMultibox });
|
||||
};
|
||||
|
||||
const handleSearchTrusts = (
|
||||
_event: React.MouseEvent<HTMLElement>,
|
||||
newSearchTrusts: string[]
|
||||
) => {
|
||||
setSearchState({ ...searchState, trusts: newSearchTrusts });
|
||||
};
|
||||
|
||||
const handleSearchLevelSync = (
|
||||
_event: React.MouseEvent<HTMLElement>,
|
||||
newSearchLevelSync: string[]
|
||||
) => {
|
||||
setSearchState({ ...searchState, levelSync: newSearchLevelSync });
|
||||
};
|
||||
|
||||
const handleSearchMaxLevelMin = (
|
||||
event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
|
||||
) => {
|
||||
let newValue = parseInt(event.target.value, 10);
|
||||
if (Number.isNaN(newValue) || newValue < 1) {
|
||||
newValue = 1;
|
||||
} else if (newValue > 99) {
|
||||
newValue = 99;
|
||||
}
|
||||
setSearchState({
|
||||
...searchState,
|
||||
maxLevel: [
|
||||
Math.min(newValue, searchState.maxLevel[1] - minDistance),
|
||||
searchState.maxLevel[1],
|
||||
],
|
||||
});
|
||||
};
|
||||
|
||||
const handleSearchMaxLevelMax = (
|
||||
event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
|
||||
) => {
|
||||
let newValue = parseInt(event.target.value, 10);
|
||||
if (Number.isNaN(newValue) || newValue < 1) {
|
||||
newValue = 1;
|
||||
} else if (newValue > 99) {
|
||||
newValue = 99;
|
||||
}
|
||||
setSearchState({
|
||||
...searchState,
|
||||
maxLevel: [
|
||||
searchState.maxLevel[0],
|
||||
Math.max(newValue, searchState.maxLevel[0] + minDistance),
|
||||
],
|
||||
});
|
||||
};
|
||||
|
||||
const handleSearchMaxLevel = (
|
||||
_event: Event,
|
||||
newValue: number | number[],
|
||||
activeThumb: number
|
||||
) => {
|
||||
if (!Array.isArray(newValue)) {
|
||||
return;
|
||||
}
|
||||
if (activeThumb === 0) {
|
||||
setSearchState({
|
||||
...searchState,
|
||||
maxLevel: [
|
||||
Math.min(newValue[0], searchState.maxLevel[1] - minDistance),
|
||||
searchState.maxLevel[1],
|
||||
],
|
||||
});
|
||||
} else {
|
||||
setSearchState({
|
||||
...searchState,
|
||||
maxLevel: [
|
||||
searchState.maxLevel[0],
|
||||
Math.max(newValue[1], searchState.maxLevel[0] + minDistance),
|
||||
],
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleSearchExpansions = (
|
||||
_event: React.MouseEvent<HTMLElement>,
|
||||
newSearchExpansions: string[]
|
||||
) => {
|
||||
if (newSearchExpansions.length === 0) {
|
||||
setSearchState({ ...searchState, expansions: null });
|
||||
} else if (
|
||||
searchState.expansions &&
|
||||
searchState.expansions.includes('none') &&
|
||||
newSearchExpansions.length > 1
|
||||
) {
|
||||
setSearchState({
|
||||
...searchState,
|
||||
expansions: newSearchExpansions.filter((item) => item !== 'none'),
|
||||
});
|
||||
} else if (
|
||||
searchState.expansions &&
|
||||
!searchState.expansions.includes('none') &&
|
||||
newSearchExpansions.includes('none')
|
||||
) {
|
||||
setSearchState({ ...searchState, expansions: ['none'] });
|
||||
} else {
|
||||
setSearchState({ ...searchState, expansions: newSearchExpansions });
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Container
|
||||
ref={containerRef}
|
||||
className="overflow-hidden"
|
||||
sx={{
|
||||
transition: 'all 0.3s ease',
|
||||
maxHeight: showSearchServer ? contentHeight : 0,
|
||||
backgroundColor: (theme) =>
|
||||
theme.palette.mode === 'dark'
|
||||
? 'rgba(255, 255, 255, .06)'
|
||||
: 'rgba(0, 0, 0, .06)',
|
||||
}}
|
||||
>
|
||||
<Grid container spacing={2} className="py-2">
|
||||
{/* Name */}
|
||||
<Grid item xs={12}>
|
||||
<TextField
|
||||
value={searchState.name}
|
||||
onChange={handleSearchName}
|
||||
variant="standard"
|
||||
autoComplete="false"
|
||||
fullWidth
|
||||
label="Name"
|
||||
size="small"
|
||||
className="pb-2"
|
||||
/>
|
||||
</Grid>
|
||||
{/* Max Level */}
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
className="pt-0"
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
alignItems="center"
|
||||
>
|
||||
<Typography id="max-level" variant="caption">
|
||||
Max Level
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} className="flex pt-0">
|
||||
<Input
|
||||
value={searchState.maxLevel[0]}
|
||||
size="small"
|
||||
onChange={handleSearchMaxLevelMin}
|
||||
// onBlur={handleBlur}
|
||||
inputProps={{
|
||||
name: 'max-level-min',
|
||||
step: 1,
|
||||
min: 1,
|
||||
max: 99,
|
||||
type: 'number',
|
||||
'aria-labelledby': 'max-level',
|
||||
}}
|
||||
/>
|
||||
<Slider
|
||||
aria-labelledby="max-level"
|
||||
value={searchState.maxLevel}
|
||||
onChange={handleSearchMaxLevel}
|
||||
valueLabelDisplay="auto"
|
||||
disableSwap
|
||||
className="mx-4"
|
||||
size="small"
|
||||
min={1}
|
||||
max={99}
|
||||
/>
|
||||
<Input
|
||||
value={searchState.maxLevel[1]}
|
||||
size="small"
|
||||
onChange={handleSearchMaxLevelMax}
|
||||
// onBlur={handleBlur}
|
||||
inputProps={{
|
||||
name: 'max-level-max',
|
||||
step: 1,
|
||||
min: 1,
|
||||
max: 99,
|
||||
type: 'number',
|
||||
'aria-labelledby': 'max-level',
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
{/* Expansion */}
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
alignItems="center"
|
||||
>
|
||||
<Tooltip
|
||||
title="Enabled expansions, exact match."
|
||||
arrow
|
||||
disableInteractive
|
||||
placement="top"
|
||||
>
|
||||
<Typography id="expansions-button-group" variant="caption">
|
||||
Expansions
|
||||
</Typography>
|
||||
</Tooltip>
|
||||
<ToggleButtonGroup
|
||||
value={searchState.expansions}
|
||||
onChange={handleSearchExpansions}
|
||||
size="small"
|
||||
aria-labelledby="expansions-button-group"
|
||||
sx={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<ToggleButton
|
||||
key="none"
|
||||
value="none"
|
||||
aria-label="none-enabled"
|
||||
className="py-0"
|
||||
sx={{ width: '20%' }}
|
||||
>
|
||||
None
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
key="rotz"
|
||||
value="rotz"
|
||||
aria-label="rotz-enabled"
|
||||
className="py-0"
|
||||
sx={{ width: '20%' }}
|
||||
>
|
||||
RotZ
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
key="cop"
|
||||
value="cop"
|
||||
aria-label="cop-enabled"
|
||||
className="py-0"
|
||||
sx={{ width: '20%' }}
|
||||
>
|
||||
CoP
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
key="toau"
|
||||
value="toau"
|
||||
aria-label="toau-enabled"
|
||||
className="py-0"
|
||||
sx={{ width: '20%' }}
|
||||
>
|
||||
ToAU
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
key="wotg"
|
||||
value="wotg"
|
||||
aria-label="wotg-enabled"
|
||||
className="py-0"
|
||||
sx={{ width: '20%' }}
|
||||
>
|
||||
WotG
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
key="soa"
|
||||
value="soa"
|
||||
aria-label="soa-enabled"
|
||||
className="py-0"
|
||||
sx={{ width: '20%' }}
|
||||
>
|
||||
SoA
|
||||
</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</Grid>
|
||||
{/* Multiboxing */}
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
alignItems="center"
|
||||
>
|
||||
<Typography id="multibox-button-group" variant="caption">
|
||||
Multiboxing
|
||||
</Typography>
|
||||
<ToggleButtonGroup
|
||||
value={searchState.multibox}
|
||||
onChange={handleSearchMultibox}
|
||||
size="small"
|
||||
aria-labelledby="multibox-button-group"
|
||||
sx={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
}}
|
||||
exclusive
|
||||
>
|
||||
<ToggleButton
|
||||
value="none"
|
||||
aria-label="no multiboxing"
|
||||
className="py-0"
|
||||
sx={{ width: '33.33%' }}
|
||||
>
|
||||
None
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
value="limited"
|
||||
aria-label="limited multiboxing"
|
||||
className="py-0"
|
||||
sx={{ width: '33.33%' }}
|
||||
>
|
||||
Limited
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
value="unlimited"
|
||||
aria-label="unlimited multiboxing"
|
||||
className="py-0"
|
||||
sx={{ width: '33.33%' }}
|
||||
>
|
||||
Unlimited
|
||||
</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</Grid>
|
||||
{/* Trusts */}
|
||||
<Grid
|
||||
item
|
||||
xs={6}
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
alignItems="center"
|
||||
>
|
||||
<Typography id="trust-button-group" variant="caption">
|
||||
Trusts
|
||||
</Typography>
|
||||
<ToggleButtonGroup
|
||||
value={searchState.trusts}
|
||||
onChange={handleSearchTrusts}
|
||||
size="small"
|
||||
aria-labelledby="trust-button-group"
|
||||
exclusive
|
||||
sx={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<ToggleButton
|
||||
value="disabled"
|
||||
aria-label="trust disabled"
|
||||
className="py-0"
|
||||
sx={{ width: '50%' }}
|
||||
>
|
||||
Disabled
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
value="enabled"
|
||||
aria-label="trust enabled"
|
||||
className="py-0"
|
||||
sx={{ width: '50%' }}
|
||||
>
|
||||
Enabled
|
||||
</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</Grid>
|
||||
{/* Level Sync */}
|
||||
<Grid
|
||||
item
|
||||
xs={6}
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
alignItems="center"
|
||||
>
|
||||
<Typography id="level-sync-button-group" variant="caption">
|
||||
Level Sync
|
||||
</Typography>
|
||||
<ToggleButtonGroup
|
||||
value={searchState.levelSync}
|
||||
onChange={handleSearchLevelSync}
|
||||
size="small"
|
||||
aria-labelledby="level-sync-button-group"
|
||||
exclusive
|
||||
sx={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<ToggleButton
|
||||
value="disabled"
|
||||
aria-label="level-sync-disabled"
|
||||
className="py-0"
|
||||
sx={{ width: '50%' }}
|
||||
>
|
||||
Disabled
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
value="enabled"
|
||||
aria-label="level-sync-enabled"
|
||||
className="py-0"
|
||||
sx={{ width: '50%' }}
|
||||
>
|
||||
Enabled
|
||||
</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Container>
|
||||
{contentHeight > 0 && <Divider />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
@ -26,16 +26,16 @@ import {
|
|||
useState,
|
||||
} from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { useThemeModeContext } from '../context/ThemeContext';
|
||||
import { ServerData } from '../data/ServerData';
|
||||
import CopyImageIcon from '../images/copy-image.png';
|
||||
import ExpansionBar from './Server/ExpansionsBar';
|
||||
import SettingsDataGrid from './Server/SettingsDataGrid';
|
||||
import { useThemeModeContext } from '../../context/ThemeContext';
|
||||
import { ServerData } from '../../data/ServerData';
|
||||
import CopyImageIcon from '../../images/copy-image.png';
|
||||
import {
|
||||
Accordion,
|
||||
AccordionDetails,
|
||||
AccordionSummary,
|
||||
} from './Themed/Accordion';
|
||||
} from '../Themed/Accordion';
|
||||
import ExpansionBar from './ExpansionsBar';
|
||||
import SettingsDataGrid from './SettingsDataGrid';
|
||||
|
||||
function scrollToTop() {
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
|
|
@ -3,6 +3,11 @@ export type SearchState = {
|
|||
multibox: string[] | null;
|
||||
trusts: string[] | null;
|
||||
levelSync: string[] | null;
|
||||
homePoint: string[] | null;
|
||||
survivalGuide: string[] | null;
|
||||
recordsOfEminence: string[] | null;
|
||||
fieldsOfValor: string[] | null;
|
||||
groundsOfValor: string[] | null;
|
||||
maxLevel: number[];
|
||||
expansions: string[] | null;
|
||||
};
|
||||
|
|
@ -12,6 +17,11 @@ export const SearchStateDefaults: SearchState = {
|
|||
multibox: null,
|
||||
trusts: null,
|
||||
levelSync: null,
|
||||
homePoint: null,
|
||||
recordsOfEminence: null,
|
||||
fieldsOfValor: null,
|
||||
groundsOfValor: null,
|
||||
survivalGuide: null,
|
||||
maxLevel: [1, 99],
|
||||
expansions: null,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { Box } from '@mui/material';
|
||||
import ErrorCard from '../components/ErrorCard';
|
||||
import ServerCard from '../components/Server/ServerCard';
|
||||
import SettingsChipCloud from '../components/Server/SettingsChipCloud';
|
||||
import ServerCard from '../components/ServerCard';
|
||||
import { SearchState } from '../data/SearchState';
|
||||
import { ServerData } from '../data/ServerData';
|
||||
|
||||
|
|
@ -13,51 +13,131 @@ export default function Home({
|
|||
searchState: SearchState;
|
||||
}) {
|
||||
const filterServers = (server: ServerData): boolean => {
|
||||
// Name
|
||||
if (searchState.name.length > 0) {
|
||||
const serverName = server.name.toLowerCase();
|
||||
if (!serverName.includes(searchState.name.toLowerCase())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Max Level
|
||||
if (server.max_level < searchState.maxLevel[0]) {
|
||||
return false;
|
||||
}
|
||||
if (server.max_level > searchState.maxLevel[1]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Trusts
|
||||
if (
|
||||
searchState.trusts &&
|
||||
typeof server.settings_summary['MAIN.ENABLE_TRUST_CASTING'] === 'number'
|
||||
) {
|
||||
const serverTrusts =
|
||||
const serverEnabled =
|
||||
server.settings_summary['MAIN.ENABLE_TRUST_CASTING'] === 1;
|
||||
const searchEnabled = searchState.trusts.includes('enabled');
|
||||
const searchDisabled = searchState.trusts.includes('disabled');
|
||||
if (serverTrusts && searchDisabled && !searchEnabled) {
|
||||
return false;
|
||||
}
|
||||
if (!serverTrusts && searchEnabled && !searchDisabled) {
|
||||
if (
|
||||
(serverEnabled && searchDisabled && !searchEnabled) ||
|
||||
(!serverEnabled && searchEnabled && !searchDisabled)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Level Sync
|
||||
if (
|
||||
searchState.levelSync &&
|
||||
typeof server.settings_summary['MAP.LEVEL_SYNC_ENABLE'] === 'boolean'
|
||||
) {
|
||||
const serverLevelSync = server.settings_summary['MAP.LEVEL_SYNC_ENABLE'];
|
||||
const serverEnabled = server.settings_summary['MAP.LEVEL_SYNC_ENABLE'];
|
||||
const searchEnabled = searchState.levelSync.includes('enabled');
|
||||
const searchDisabled = searchState.levelSync.includes('disabled');
|
||||
if (serverLevelSync && searchDisabled && !searchEnabled) {
|
||||
return false;
|
||||
}
|
||||
if (!serverLevelSync && searchEnabled && !searchDisabled) {
|
||||
if (
|
||||
(serverEnabled && searchDisabled && !searchEnabled) ||
|
||||
(!serverEnabled && searchEnabled && !searchDisabled)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Home Point Teleport
|
||||
if (
|
||||
searchState.homePoint &&
|
||||
typeof server.settings_summary['MAIN.HOMEPOINT_TELEPORT'] === 'number'
|
||||
) {
|
||||
const serverEnabled =
|
||||
server.settings_summary['MAIN.HOMEPOINT_TELEPORT'] === 1;
|
||||
const searchEnabled = searchState.homePoint.includes('enabled');
|
||||
const searchDisabled = searchState.homePoint.includes('disabled');
|
||||
if (
|
||||
(serverEnabled && searchDisabled && !searchEnabled) ||
|
||||
(!serverEnabled && searchEnabled && !searchDisabled)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Survival Guides
|
||||
if (
|
||||
searchState.survivalGuide &&
|
||||
typeof server.settings_summary['MAIN.ENABLE_SURVIVAL_GUIDE'] === 'number'
|
||||
) {
|
||||
const serverEnabled =
|
||||
server.settings_summary['MAIN.ENABLE_SURVIVAL_GUIDE'] === 1;
|
||||
const searchEnabled = searchState.survivalGuide.includes('enabled');
|
||||
const searchDisabled = searchState.survivalGuide.includes('disabled');
|
||||
if (
|
||||
(serverEnabled && searchDisabled && !searchEnabled) ||
|
||||
(!serverEnabled && searchEnabled && !searchDisabled)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Records of Eminence
|
||||
if (
|
||||
searchState.recordsOfEminence &&
|
||||
typeof server.settings_summary['MAIN.ENABLE_ROE'] === 'number'
|
||||
) {
|
||||
const serverEnabled = server.settings_summary['MAIN.ENABLE_ROE'] === 1;
|
||||
const searchEnabled = searchState.recordsOfEminence.includes('enabled');
|
||||
const searchDisabled = searchState.recordsOfEminence.includes('disabled');
|
||||
if (
|
||||
(serverEnabled && searchDisabled && !searchEnabled) ||
|
||||
(!serverEnabled && searchEnabled && !searchDisabled)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Fields of Valor
|
||||
if (
|
||||
searchState.fieldsOfValor &&
|
||||
typeof server.settings_summary['MAIN.ENABLE_FIELD_MANUALS'] === 'number'
|
||||
) {
|
||||
const serverEnabled =
|
||||
server.settings_summary['MAIN.ENABLE_FIELD_MANUALS'] === 1;
|
||||
const searchEnabled = searchState.fieldsOfValor.includes('enabled');
|
||||
const searchDisabled = searchState.fieldsOfValor.includes('disabled');
|
||||
if (
|
||||
(serverEnabled && searchDisabled && !searchEnabled) ||
|
||||
(!serverEnabled && searchEnabled && !searchDisabled)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Grounds of Valor
|
||||
if (
|
||||
searchState.groundsOfValor &&
|
||||
typeof server.settings_summary['MAIN.ENABLE_GROUNDS_TOMES'] === 'number'
|
||||
) {
|
||||
const serverEnabled =
|
||||
server.settings_summary['MAIN.ENABLE_GROUNDS_TOMES'] === 1;
|
||||
const searchEnabled = searchState.groundsOfValor.includes('enabled');
|
||||
const searchDisabled = searchState.groundsOfValor.includes('disabled');
|
||||
if (
|
||||
(serverEnabled && searchDisabled && !searchEnabled) ||
|
||||
(!serverEnabled && searchEnabled && !searchDisabled)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Expansions
|
||||
if (searchState.expansions) {
|
||||
if (!server.expansions) {
|
||||
return false;
|
||||
|
|
@ -72,23 +152,23 @@ export default function Home({
|
|||
) {
|
||||
return false;
|
||||
}
|
||||
if (searchState.expansions.includes('rotz') && server.expansions.rotz) {
|
||||
if (searchState.expansions.includes('rotz') !== server.expansions.rotz) {
|
||||
return false;
|
||||
}
|
||||
if (searchState.expansions.includes('cop') && server.expansions.cop) {
|
||||
if (searchState.expansions.includes('cop') !== server.expansions.cop) {
|
||||
return false;
|
||||
}
|
||||
if (searchState.expansions.includes('toau') && server.expansions.toau) {
|
||||
if (searchState.expansions.includes('toau') !== server.expansions.toau) {
|
||||
return false;
|
||||
}
|
||||
if (searchState.expansions.includes('wotg') && server.expansions.wotg) {
|
||||
if (searchState.expansions.includes('wotg') !== server.expansions.wotg) {
|
||||
return false;
|
||||
}
|
||||
if (searchState.expansions.includes('soa') && server.expansions.soa) {
|
||||
if (searchState.expansions.includes('soa') !== server.expansions.soa) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Multibox
|
||||
if (searchState.multibox) {
|
||||
const serverMultibox = server.login_limit;
|
||||
if (searchState.multibox.includes('none') && serverMultibox !== 1) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ import { useEffect, useState } from 'react';
|
|||
import { useParams } from 'react-router-dom';
|
||||
import { fetchDataFromBackend, fetchDemo } from '../apiUtil';
|
||||
import ErrorCard from '../components/ErrorCard';
|
||||
import ServerCard from '../components/Server/ServerCard';
|
||||
import SettingsDataGrid from '../components/Server/SettingsDataGrid';
|
||||
import ServerCard from '../components/ServerCard';
|
||||
import { useLoadingContext } from '../context/LoadingContext';
|
||||
import { ServerData } from '../data/ServerData';
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue