Implement a page navigation button

Improve page loading and theme system
- The sidebar is visible while loading with css
  There was an apparent problem when switching pages with the new switcher
- css variables are now used
- Theme color is applied to several buttons and texts
  where previously Plan color was used

Affects issues:
- Implements #2357
This commit is contained in:
Aurora Lahtela 2023-01-26 14:18:51 +02:00
parent b1a63d57b6
commit 362bb44aad
20 changed files with 522 additions and 397 deletions

View File

@ -4,7 +4,7 @@ import './style/style.css';
import {BrowserRouter, Navigate, Route, Routes} from "react-router-dom";
import React from "react";
import {ThemeContextProvider} from "./hooks/themeHook";
import {NightModeCss, ThemeContextProvider, ThemeCss} from "./hooks/themeHook";
import axios from "axios";
import ErrorView from "./views/ErrorView";
import {faMapSigns} from "@fortawesome/free-solid-svg-icons";
@ -99,8 +99,10 @@ function App() {
return (
<div className="App">
<ContextProviders>
<ThemeCss/>
<div id="wrapper">
<BrowserRouter basename={getBasename()}>
<NightModeCss/>
<Routes>
<Route path="" element={<MainPageRedirect/>}/>
<Route path="/" element={<MainPageRedirect/>}/>

View File

@ -227,7 +227,7 @@ const QueryOptionsCard = () => {
</Row>
</Card.Body>
<button id={"query-button"}
className={"btn bg-plan m-2"}
className={"btn bg-theme m-2"}
disabled={Boolean(invalidFields.length) || loadingResults}
onClick={performQuery}>
<FontAwesomeIcon icon={loadingResults ? faGear : faSearch}

View File

@ -31,9 +31,9 @@ const ColorSelectorModal = () => {
<button aria-label="Close" className="btn-close" onClick={theme.toggleColorChooser}/>
</Modal.Header>
<Modal.Body style={{padding: "0.5rem 0 0.5rem 0.5rem"}}>
{theme.themeColors.map((color, i) =>
{theme.themeColors.map(color =>
<ColorSelectorButton
key={i}
key={color.name}
color={color.name}
setColor={theme.setColor}
disabled={theme.nightModeEnabled}
@ -43,7 +43,7 @@ const ColorSelectorModal = () => {
<button className="btn" id="night-mode-toggle" type="button" onClick={theme.toggleNightMode}>
<Fa icon={faCloudMoon}/> {t('html.button.nightMode')}
</button>
<button className="btn bg-plan" type="button" onClick={theme.toggleColorChooser}>OK</button>
<button className="btn bg-theme" type="button" onClick={theme.toggleColorChooser}>OK</button>
</Modal.Footer>
</Modal>
)

View File

@ -30,14 +30,14 @@ const LicenseSection = () => {
const Links = () => {
const {t} = useTranslation();
return (<>
<a className="btn col-plan" href="https://github.com/plan-player-analytics/Plan/wiki"
<a className="btn col-theme" href="https://github.com/plan-player-analytics/Plan/wiki"
rel="noopener noreferrer" target="_blank">
<Fa icon={faGraduationCap}/> {t('html.modal.info.wiki')}
</a>
<a className="btn col-plan" href="https://github.com/plan-player-analytics/Plan/issues"
<a className="btn col-theme" href="https://github.com/plan-player-analytics/Plan/issues"
rel="noopener noreferrer" target="_blank">
<Fa icon={faBug}/> {t('html.modal.info.bugs')}</a>
<a className="btn col-plan" href="https://discord.gg/yXKmjzT" rel="noopener noreferrer"
<a className="btn col-theme" href="https://discord.gg/yXKmjzT" rel="noopener noreferrer"
target="_blank">
<Fa icon={faDiscord}/> {t('html.modal.info.discord')}
</a>
@ -75,7 +75,7 @@ const Contributions = () => {
// TODO Translate
return (<>
<p>Player Analytics {t('html.modal.info.developer')} AuroraLS3.</p>
<p>In addition following <span className="col-plan">awesome people</span> have
<p>In addition following <span className="col-theme">awesome people</span> have
contributed:</p>
<ul className="row contributors">
{contributors.map((contributor, i) => <Contributor key={i} contributor={contributor}/>)}
@ -86,7 +86,7 @@ const Contributions = () => {
icon={faLanguage}/> {t('html.modal.info.contributors.translator')}
</small>
<hr/>
<p className="col-plan">
<p className="col-theme">
{t('html.modal.info.contributors.donate')}
<Fa icon={faStar} className={"col-amber"}/>
</p>
@ -98,19 +98,19 @@ const MetricsLinks = () => {
return (
<>
<h6>{t('html.modal.info.metrics')}</h6>
<a className="btn col-plan" href="https://bstats.org/plugin/bukkit/Plan"
<a className="btn col-theme" href="https://bstats.org/plugin/bukkit/Plan"
rel="noopener noreferrer" target="_blank">
<Fa icon={faChartArea}/> Bukkit
</a>
<a className="btn col-plan" href="https://bstats.org/plugin/bungeecord/Plan"
<a className="btn col-theme" href="https://bstats.org/plugin/bungeecord/Plan"
rel="noopener noreferrer" target="_blank">
<Fa icon={faChartArea}/> BungeeCord
</a>
<a className="btn col-plan" href="https://bstats.org/plugin/sponge/plan"
<a className="btn col-theme" href="https://bstats.org/plugin/sponge/plan"
rel="noopener noreferrer" target="_blank">
<Fa icon={faChartArea}/> Sponge
</a>
<a className="btn col-plan" href="https://bstats.org/plugin/velocity/Plan/10326"
<a className="btn col-theme" href="https://bstats.org/plugin/velocity/Plan/10326"
rel="noopener noreferrer" target="_blank">
<Fa icon={faChartArea}/> Velocity
</a>
@ -138,7 +138,7 @@ const PluginInformationModal = ({open, toggle}) => {
<MetricsLinks/>
</Modal.Body>
<Modal.Footer>
<button className="btn bg-plan" onClick={toggle}>OK</button>
<button className="btn bg-theme" onClick={toggle}>OK</button>
</Modal.Footer>
</Modal>
)

View File

@ -20,15 +20,15 @@ const UpdateAvailableModal = ({open, toggle, versionInfo}) => {
<p>You have version {versionInfo.currentVersion}.</p>
<p>New
release: {versionInfo.newVersion}{versionInfo.isRelease ? '' : " (" + t('html.modal.version.dev') + ")"}</p>
<a className="btn col-plan" href={versionInfo.changelogUrl} rel="noopener noreferrer" target="_blank">
<a className="btn col-theme" href={versionInfo.changelogUrl} rel="noopener noreferrer" target="_blank">
{t('html.modal.version.changelog')}
</a>
<a className="btn col-plan" href={versionInfo.downloadUrl} rel="noopener noreferrer" target="_blank">
<a className="btn col-theme" href={versionInfo.downloadUrl} rel="noopener noreferrer" target="_blank">
{t('html.modal.version.download')} Plan-{versionInfo.newVersion}.jar
</a>
</Modal.Body>
<Modal.Footer>
<button className="btn bg-plan" onClick={toggle}>OK</button>
<button className="btn bg-theme" onClick={toggle}>OK</button>
</Modal.Footer>
</Modal>
)
@ -47,7 +47,7 @@ const NewestVersionModal = ({open, toggle, versionInfo}) => {
You're using the latest version {versionInfo.currentVersion}. (No updates available)
</Modal.Body>
<Modal.Footer>
<button className="btn bg-plan" onClick={toggle}>OK</button>
<button className="btn bg-theme" onClick={toggle}>OK</button>
</Modal.Footer>
</Modal>
);

View File

@ -0,0 +1,89 @@
import React, {useEffect, useState} from 'react';
import {faCompass} from "@fortawesome/free-solid-svg-icons";
import {useTranslation} from "react-i18next";
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
import {InputGroup} from "react-bootstrap-v5";
import {useLocation, useNavigate} from "react-router-dom";
import {useMetadata} from "../../hooks/metadataHook";
import {useAuth} from "../../hooks/authenticationHook";
const PageNavigationItem = ({page}) => {
const {t} = useTranslation();
const navigate = useNavigate();
const location = useLocation();
const {authRequired, loggedIn, user} = useAuth();
const {networkMetadata} = useMetadata();
const [currentPage, setCurrentPage] = useState(undefined);
const [items, setItems] = useState([]);
useEffect(() => {
if (networkMetadata) {
let newItems = [
{id: 'network', displayName: t('html.label.network'), href: "/network", permission: 'page.network'},
{id: 'players', displayName: t('html.label.players'), href: "/players", permission: 'page.players'},
{
id: 'query',
displayName: t('html.query.title.text').replace('<', ''),
href: "/query",
permission: 'page.players'
},
...networkMetadata.servers
.filter(server => !server.proxy)
.map(server => {
return {
id: 'server-' + server.serverUUID,
displayName: t('html.label.server') + ', ' + server.serverName,
href: '/server/' + server.serverUUID,
permission: 'page.server'
}
})
];
if (page) {
newItems.unshift({id: 'page', displayName: page, href: location.pathname, permission: undefined})
}
if (authRequired && loggedIn) {
newItems = newItems.filter(item => item.permission && user.permissions.includes(item.permission))
}
setItems(newItems);
setCurrentPage(newItems.find(item => location.pathname.startsWith(item.href))?.id);
}
}, [t, networkMetadata, location, authRequired, loggedIn, user, page]);
const onSelect = ({target}) => {
const selected = target.value;
navigate(items.find(item => item.id === selected).href);
}
if (!currentPage || !items.length) {
return <li className={"nav-item nav-button nav-link"}
style={{
padding: "0.5rem",
paddingLeft: "1rem",
paddingRight: "1rem"
}}>
<p className={"p-0 m-0"}>&nbsp;</p>
</li>
}
return (
<li className={"nav-item nav-button nav-link"}
style={{padding: "1rem"}}>
<InputGroup>
<div className="input-group-text bg-theme col-white"
style={{paddingLeft: "0.5rem", paddingRight: "0.5rem"}}><Fa icon={faCompass}/></div>
<select onChange={onSelect}
aria-label="Page selector"
className="form-select form-select-sm scrollbar"
id="pageSelector"
defaultValue={currentPage}>
{items.map((item, i) =>
<option key={i} value={item.id}>{item.displayName}</option>)}
</select>
</InputGroup>
</li>
)
};
export default PageNavigationItem

View File

@ -1,7 +1,7 @@
import React, {useCallback, useEffect, useState} from "react";
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
import logo from '../../Flaticon_circle.png';
import {faArrowLeft, faDoorOpen, faDownload, faPalette, faQuestionCircle} from "@fortawesome/free-solid-svg-icons";
import {faDoorOpen, faDownload, faPalette, faQuestionCircle} from "@fortawesome/free-solid-svg-icons";
import {NavLink, useLocation} from "react-router-dom";
import {useTheme} from "../../hooks/themeHook";
import PluginInformationModal from "../modal/PluginInformationModal";
@ -12,6 +12,7 @@ import {useNavigation} from "../../hooks/navigationHook";
import {useTranslation} from "react-i18next";
import {Collapse} from "react-bootstrap-v5";
import {baseAddress} from "../../service/backendConfiguration";
import PageNavigationItem from "./PageNavigationItem";
const Logo = () => (
<a className="sidebar-brand d-flex align-items-center justify-content-center" href="/">
@ -44,7 +45,7 @@ const InnerItem = ({href, icon, name, nameShort, color, external}) => {
</NavLink>
}
const Item = ({item, inner}) => {
export const Item = ({item, inner}) => {
const {setCurrentTab} = useNavigation();
const {pathname} = useLocation();
const {t} = useTranslation();
@ -84,7 +85,7 @@ const Item = ({item, inner}) => {
const VersionButton = ({toggleVersionModal, versionInfo}) => {
if (versionInfo.updateAvailable) {
return <button className="btn bg-white col-plan" onClick={toggleVersionModal}>
return <button className="btn bg-white col-theme" onClick={toggleVersionModal}>
<Fa icon={faDownload}/> Update Available!
</button>;
}
@ -203,9 +204,8 @@ const renderItem = (item, i, openCollapse, setOpenCollapse, t) => {
return <hr key={i} className="sidebar-divider"/>
}
const Sidebar = ({items, showBackButton}) => {
const Sidebar = ({page, items}) => {
const {t} = useTranslation();
const {color} = useTheme();
const {currentTab, sidebarExpanded, setSidebarExpanded} = useNavigation();
const [openCollapse, setOpenCollapse] = useState(undefined);
@ -226,13 +226,10 @@ const Sidebar = ({items, showBackButton}) => {
return (
<>
{sidebarExpanded &&
<ul className={"navbar-nav sidebar sidebar-dark accordion bg-" + color} id="accordionSidebar">
<ul className={"navbar-nav sidebar sidebar-dark accordion bg-theme"} id="accordionSidebar">
<Logo/>
<Divider/>
{showBackButton && <>
<Item active={false} item={{href: "/", icon: faArrowLeft, name: t('html.label.toMainPage')}}/>
<Divider showMargin={items.length && !items[0].contents && items[0].href === undefined}/>
</>}
<PageNavigationItem page={page}/>
<Divider showMargin={items.length && !items[0].contents && items[0].href === undefined}/>
{items.length ? items.filter(item => item !== undefined).map((item, i) => renderItem(item, i, openCollapse, toggleCollapse, t)) : ''}
<Divider/>
<FooterButtons/>

View File

@ -1,7 +1,8 @@
import {createContext, useContext, useState} from "react";
import {createContext, useContext, useMemo, useState} from "react";
import {createNightModeCss, getColors} from "../util/colors";
import {getLightModeChartTheming, getNightModeChartTheming} from "../util/graphColors";
import {useMetadata} from "./metadataHook";
import {useLocation} from "react-router-dom";
const themeColors = getColors();
themeColors.splice(themeColors.length - 4, 4);
@ -40,14 +41,13 @@ export const ThemeContextProvider = ({children}) => {
const [selectedColor, setSelectedColor] = useState(getStoredTheme(getDefaultTheme(metadata)));
const [previousColor, setPreviousColor] = useState(undefined);
const sharedState = {
selectedColor,
setSelectedColor,
previousColor,
setPreviousColor,
colorChooserOpen,
setColorChooserOpen
}
const sharedState = useMemo(() => {
return {
selectedColor, setSelectedColor,
previousColor, setPreviousColor,
colorChooserOpen, setColorChooserOpen
}
}, [selectedColor, setSelectedColor, previousColor, setPreviousColor, colorChooserOpen, setColorChooserOpen]);
return (<ThemeContext.Provider value={sharedState}>
{children}
</ThemeContext.Provider>
@ -107,8 +107,29 @@ export const useTheme = () => {
};
}
export const ThemeCss = () => {
const {color} = useTheme();
if (!color) return <></>;
return (
<style>
{':root {--color-theme: var(--color-' + color + ') !important;}'}
</style>
)
}
export const NightModeCss = () => {
const theme = useTheme();
const location = useLocation();
if (location.pathname.startsWith('/docs')) {
return <>
<style>
{'#wrapper {background-image: none;}'}
</style>
</>
}
return (
<>

View File

@ -1670,22 +1670,10 @@ select.form-control:focus::-ms-value {
background-color: #858796 !important;
}
.bg-success {
background-color: #1cc88a !important;
}
.bg-info {
background-color: #36b9cc !important;
}
.bg-warning {
background-color: #f6c23e !important;
}
.bg-danger {
background-color: #e74a3b !important;
}
.bg-light {
background-color: #f8f9fc !important;
}
@ -1866,11 +1854,6 @@ a.text-dark:hover, a.text-dark:focus {
}
}
#wrapper {
display: flex;
min-height: 100vh;
}
#wrapper #content-wrapper {
background-color: #f8f9fc;
width: 100%;
@ -2575,145 +2558,145 @@ a.text-dark:hover, a.text-dark:focus {
}
/*@media (min-width: 768px) { Commented because mobile should have full width sidebar when open. */
.sidebar {
width: 14rem !important;
}
.sidebar {
width: 14rem !important;
}
.sidebar .nav-item .collapse {
position: relative;
left: 0;
z-index: 1;
top: 0;
-webkit-animation: none;
animation: none;
}
.sidebar .nav-item .collapse {
position: relative;
left: 0;
z-index: 1;
top: 0;
-webkit-animation: none;
animation: none;
}
.sidebar .nav-item .collapse .collapse-inner {
border-radius: 0;
box-shadow: none;
}
.sidebar .nav-item .collapse .collapse-inner {
border-radius: 0;
box-shadow: none;
}
.sidebar .nav-item .collapsing {
display: block;
transition: height 0.15s ease;
}
.sidebar .nav-item .collapsing {
display: block;
transition: height 0.15s ease;
}
.sidebar .nav-item .collapse,
.sidebar .nav-item .collapsing {
margin: 0 1rem;
}
.sidebar .nav-item .collapse,
.sidebar .nav-item .collapsing {
margin: 0 1rem;
}
.sidebar .nav-item .nav-link {
display: block;
width: 14rem;
text-align: left;
padding: 1rem;
}
.sidebar .nav-item .nav-link {
display: block;
width: 14rem;
text-align: left;
padding: 1rem;
}
.sidebar .nav-item .nav-link i, .sidebar .nav-item .nav-link svg {
font-size: 0.85rem;
margin-right: 0.25rem;
}
.sidebar .nav-item .nav-link i, .sidebar .nav-item .nav-link svg {
font-size: 0.85rem;
margin-right: 0.25rem;
}
.sidebar .nav-item .nav-link span {
font-size: 0.85rem;
display: inline;
}
.sidebar .nav-item .nav-link span {
font-size: 0.85rem;
display: inline;
}
.sidebar .nav-item .nav-link[data-bs-toggle="collapse"]::after {
width: 1rem;
text-align: center;
float: right;
vertical-align: 0;
border: 0;
font-weight: 900;
content: '\f107';
font-family: 'Font Awesome 5 Free';
}
.sidebar .nav-item .nav-link[data-bs-toggle="collapse"]::after {
width: 1rem;
text-align: center;
float: right;
vertical-align: 0;
border: 0;
font-weight: 900;
content: '\f107';
font-family: 'Font Awesome 5 Free';
}
.sidebar .nav-item .nav-link[data-bs-toggle="collapse"].collapsed::after {
content: '\f105';
}
.sidebar .nav-item .nav-link[data-bs-toggle="collapse"].collapsed::after {
content: '\f105';
}
.sidebar .sidebar-brand .sidebar-brand-icon i {
font-size: 2rem;
}
.sidebar .sidebar-brand .sidebar-brand-icon i {
font-size: 2rem;
}
.sidebar .sidebar-brand .sidebar-brand-text {
display: inline;
}
.sidebar .sidebar-brand .sidebar-brand-text {
display: inline;
}
.sidebar .sidebar-heading {
text-align: left;
}
.sidebar .sidebar-heading {
text-align: left;
}
.sidebar.toggled {
overflow: visible;
width: 6.5rem !important;
}
.sidebar.toggled {
overflow: visible;
width: 6.5rem !important;
}
.sidebar.toggled .nav-item .collapse {
position: absolute;
left: calc(6.5rem + 1.5rem / 2);
z-index: 1;
top: 2px;
-webkit-animation-name: growIn;
animation-name: growIn;
-webkit-animation-duration: 200ms;
animation-duration: 200ms;
-webkit-animation-timing-function: transform cubic-bezier(0.18, 1.25, 0.4, 1), opacity cubic-bezier(0, 1, 0.4, 1);
animation-timing-function: transform cubic-bezier(0.18, 1.25, 0.4, 1), opacity cubic-bezier(0, 1, 0.4, 1);
}
.sidebar.toggled .nav-item .collapse {
position: absolute;
left: calc(6.5rem + 1.5rem / 2);
z-index: 1;
top: 2px;
-webkit-animation-name: growIn;
animation-name: growIn;
-webkit-animation-duration: 200ms;
animation-duration: 200ms;
-webkit-animation-timing-function: transform cubic-bezier(0.18, 1.25, 0.4, 1), opacity cubic-bezier(0, 1, 0.4, 1);
animation-timing-function: transform cubic-bezier(0.18, 1.25, 0.4, 1), opacity cubic-bezier(0, 1, 0.4, 1);
}
.sidebar.toggled .nav-item .collapse .collapse-inner {
box-shadow: 0 0.15rem 1.75rem 0 rgba(58, 59, 69, 0.15);
border-radius: 0.35rem;
}
.sidebar.toggled .nav-item .collapse .collapse-inner {
box-shadow: 0 0.15rem 1.75rem 0 rgba(58, 59, 69, 0.15);
border-radius: 0.35rem;
}
.sidebar.toggled .nav-item .collapsing {
display: none;
transition: none;
}
.sidebar.toggled .nav-item .collapsing {
display: none;
transition: none;
}
.sidebar.toggled .nav-item .collapse,
.sidebar.toggled .nav-item .collapsing {
margin: 0;
}
.sidebar.toggled .nav-item .collapse,
.sidebar.toggled .nav-item .collapsing {
margin: 0;
}
.sidebar.toggled .nav-item:last-child {
margin-bottom: 1rem;
}
.sidebar.toggled .nav-item:last-child {
margin-bottom: 1rem;
}
.sidebar.toggled .nav-item .nav-link {
text-align: center;
padding: 0.75rem 1rem;
width: 6.5rem;
}
.sidebar.toggled .nav-item .nav-link {
text-align: center;
padding: 0.75rem 1rem;
width: 6.5rem;
}
.sidebar.toggled .nav-item .nav-link span {
font-size: 0.65rem;
display: block;
}
.sidebar.toggled .nav-item .nav-link span {
font-size: 0.65rem;
display: block;
}
.sidebar.toggled .nav-item .nav-link i, .sidebar.toggled .nav-item .nav-link svg {
margin-right: 0;
}
.sidebar.toggled .nav-item .nav-link i, .sidebar.toggled .nav-item .nav-link svg {
margin-right: 0;
}
.sidebar.toggled .nav-item .nav-link[data-bs-toggle="collapse"]::after {
display: none;
}
.sidebar.toggled .nav-item .nav-link[data-bs-toggle="collapse"]::after {
display: none;
}
.sidebar.toggled .sidebar-brand .sidebar-brand-icon i {
font-size: 2rem;
}
.sidebar.toggled .sidebar-brand .sidebar-brand-icon i {
font-size: 2rem;
}
.sidebar.toggled .sidebar-brand .sidebar-brand-text {
display: none;
}
.sidebar.toggled .sidebar-brand .sidebar-brand-text {
display: none;
}
.sidebar.toggled .sidebar-heading {
text-align: center;
}
.sidebar.toggled .sidebar-heading {
text-align: center;
}
/*}*/

View File

@ -1,3 +1,44 @@
:root {
--color-red: #F44336;
--color-pink: #E91E63;
--color-purple: #9C27B0;
--color-deep-purple: #673AB7;
--color-indigo: #3F51B5;
--color-blue: #2196F3;
--color-light-blue: #03A9F4;
--color-cyan: #00BCD4;
--color-teal: #009688;
--color-green: #4CAF50;
--color-light-green: #8BC34A;
--color-lime: #CDDC39;
--color-yellow: #ffe821;
--color-amber: #FFC107;
--color-orange: #FF9800;
--color-deep-orange: #FF5722;
--color-brown: #795548;
--color-grey: #9E9E9E;
--color-blue-grey: #607D8B;
--color-black: #555555;
--color-white: #ffffff;
--color-plan: #368F17;
--color-text-light-bg: #333;
--color-text-dark-bg: #fff;
--color-text-dark-bg-disabled: #ccc;
--color-success: #1CC88A;
--color-warning: #F6C23E;
--color-danger: #e74A3B;
--color-night-black: #282a36;
--color-night-dark-blue: #44475a;
--color-night-blue: #6272a4;
--color-night-grey-blue: #646e8c;
--color-night-dark-grey-blue: #606270;
--color-night-text-dark-bg: #eee8d5;
--color-theme: var(--color-plan);
}
a {
text-decoration: none;
}
@ -132,9 +173,9 @@ p.collapsing {
display: inline-block;
width: 2rem;
height: 2rem;
border: 4px solid #368F17;
border: 4px solid var(--color-theme);
background-color: var(--color-theme);
border-radius: 5px;
background-color: #368F17;
animation: loader 2s infinite ease;
}
@ -767,135 +808,153 @@ div#navSrvContainer::-webkit-scrollbar-thumb {
}
.bg-red, body.theme-red .fc-toolbar-chunk .btn.btn-primary {
background-color: #F44336;
--bs-btn-disabled-bg: #F44336;
color: #fff;
background-color: var(--color-red);
--bs-btn-disabled-bg: var(--color-red);
color: var(--color-text-dark-bg);
}
.bg-pink, body.theme-pink .fc-toolbar-chunk .btn.btn-primary {
background-color: #E91E63;
--bs-btn-disabled-bg: #E91E63;
color: #fff;
background-color: var(--color-pink);
--bs-btn-disabled-bg: var(--color-pink);
color: var(--color-text-dark-bg);
}
.bg-purple, body.theme-purple .fc-toolbar-chunk .btn.btn-primary {
background-color: #9C27B0;
--bs-btn-disabled-bg: #9C27B0;
color: #fff;
background-color: var(--color-purple);
--bs-btn-disabled-bg: var(--color-purple);
color: var(--color-text-dark-bg);
}
.bg-deep-purple, body.theme-deep-purple .fc-toolbar-chunk .btn.btn-primary {
background-color: #673AB7;
--bs-btn-disabled-bg: #673AB7;
color: #fff;
background-color: var(--color-deep-purple);
--bs-btn-disabled-bg: var(--color-deep-purple);
color: var(--color-text-dark-bg);
}
.bg-indigo, body.theme-indigo .fc-toolbar-chunk .btn.btn-primary {
background-color: #3F51B5;
--bs-btn-disabled-bg: #3F51B5;
color: #fff;
background-color: var(--color-indigo);
--bs-btn-disabled-bg: var(--color-indigo);
color: var(--color-text-dark-bg);
}
.bg-blue, body.theme-blue .fc-toolbar-chunk .btn.btn-primary {
background-color: #2196F3;
--bs-btn-disabled-bg: #2196F3;
color: #fff;
background-color: var(--color-blue);
--bs-btn-disabled-bg: var(--color-blue);
color: var(--color-text-dark-bg);
}
.bg-light-blue, body.theme-light-blue .fc-toolbar-chunk .btn.btn-primary {
background-color: #03A9F4;
--bs-btn-disabled-bg: #03A9F4;
color: #fff;
background-color: var(--color-light-blue);
--bs-btn-disabled-bg: var(--color-light-blue);
color: var(--color-text-dark-bg);
}
.bg-cyan, body.theme-cyan .fc-toolbar-chunk .btn.btn-primary {
background-color: #00BCD4;
--bs-btn-disabled-bg: #00BCD4;
color: #fff;
background-color: var(--color-cyan);
--bs-btn-disabled-bg: var(--color-cyan);
color: var(--color-text-dark-bg);
}
.bg-teal, body.theme-teal .fc-toolbar-chunk .btn.btn-primary {
background-color: #009688;
--bs-btn-disabled-bg: #009688;
color: #fff;
background-color: var(--color-teal);
--bs-btn-disabled-bg: var(--color-teal);
color: var(--color-text-dark-bg);
}
.bg-green, body.theme-green .fc-toolbar-chunk .btn.btn-primary {
background-color: #4CAF50;
--bs-btn-disabled-bg: #4CAF50;
color: #fff;
background-color: var(--color-green);
--bs-btn-disabled-bg: var(--color-green);
color: var(--color-text-dark-bg);
}
.bg-light-green, body.theme-light-green .fc-toolbar-chunk .btn.btn-primary {
background-color: #8BC34A;
--bs-btn-disabled-bg: #8BC34A;
color: #fff;
background-color: var(--color-light-green);
--bs-btn-disabled-bg: var(--color-light-green);
color: var(--color-text-dark-bg);
}
.bg-lime, body.theme-lime .fc-toolbar-chunk .btn.btn-primary {
background-color: #CDDC39;
--bs-btn-disabled-bg: #CDDC39;
color: #fff;
background-color: var(--color-lime);
--bs-btn-disabled-bg: var(--color-lime);
color: var(--color-text-dark-bg);
}
.bg-yellow, body.theme-yellow .fc-toolbar-chunk .btn.btn-primary {
background-color: #ffe821;
--bs-btn-disabled-bg: #ffe821;
color: #fff;
background-color: var(--color-yellow);
--bs-btn-disabled-bg: var(--color-yellow);
color: var(--color-text-dark-bg);
}
.bg-amber, body.theme-amber .fc-toolbar-chunk .btn.btn-primary {
background-color: #FFC107;
--bs-btn-disabled-bg: #FFC107;
color: #fff;
background-color: var(--color-amber);
--bs-btn-disabled-bg: var(--color-amber);
color: var(--color-text-dark-bg);
}
.bg-orange, body.theme-orange .fc-toolbar-chunk .btn.btn-primary {
background-color: #FF9800;
--bs-btn-disabled-bg: #FF9800;
color: #fff;
background-color: var(--color-orange);
--bs-btn-disabled-bg: var(--color-orange);
color: var(--color-text-dark-bg);
}
.bg-deep-orange, body.theme-deep-orange .fc-toolbar-chunk .btn.btn-primary {
background-color: #FF5722;
--bs-btn-disabled-bg: #FF5722;
color: #fff;
background-color: var(--color-deep-orange);
--bs-btn-disabled-bg: var(--color-deep-orange);
color: var(--color-text-dark-bg);
}
.bg-brown, body.theme-brown .fc-toolbar-chunk .btn.btn-primary {
background-color: #795548;
--bs-btn-disabled-bg: #795548;
color: #fff;
background-color: var(--color-brown);
--bs-btn-disabled-bg: var(--color-brown);
color: var(--color-text-dark-bg);
}
.bg-grey, body.theme-grey .fc-toolbar-chunk .btn.btn-primary {
background-color: #9E9E9E;
--bs-btn-disabled-bg: #9E9E9E;
color: #fff;
background-color: var(--color-grey);
--bs-btn-disabled-bg: var(--color-grey);
color: var(--color-text-dark-bg);
}
.bg-blue-grey, body.theme-blue-grey .fc-toolbar-chunk .btn.btn-primary {
background-color: #607D8B;
--bs-btn-disabled-bg: #607D8B;
color: #fff;
background-color: var(--color-blue-grey);
--bs-btn-disabled-bg: var(--color-blue-grey);
color: var(--color-text-dark-bg);
}
.bg-black, body.theme-black .fc-toolbar-chunk .btn.btn-primary {
background-color: #555555;
--bs-btn-disabled-bg: #555555;
color: #fff;
background-color: var(--color-black);
--bs-btn-disabled-bg: var(--color-black);
color: var(--color-text-dark-bg);
}
.bg-white, body.theme-white .fc-toolbar-chunk .btn.btn-primary {
background-color: #ffffff;
--bs-btn-disabled-bg: #ffffff;
color: #333;
background-color: var(--color-white);
--bs-btn-disabled-bg: var(--color-white);
color: var(--color-text-light-bg);
}
.bg-plan, body.theme-plan .fc-toolbar-chunk .btn.btn-primary {
background-color: #368F17;
--bs-btn-disabled-bg: #368F17;
color: #fff;
background-color: var(--color-plan);
--bs-btn-disabled-bg: var(--color-plan);
color: var(--color-text-dark-bg);
}
.bg-theme, body.theme .fc-toolbar-chunk .btn.btn-primary {
background-color: var(--color-theme);
--bs-btn-disabled-bg: var(--color-theme);
color: var(--color-text-dark-bg);
}
.bg-success {
background-color: var(--color-success) !important;
}
.bg-warning {
background-color: var(--color-warning) !important;
}
.bg-danger {
background-color: var(--color-danger) !important;
}
.btn.bg-plan:hover,
@ -920,14 +979,14 @@ div#navSrvContainer::-webkit-scrollbar-thumb {
.btn.bg-grey:hover,
.btn.bg-blue-grey:hover,
.btn.bg-transparent-light:hover {
color: #ccc !important;
color: var(--color-text-dark-bg-disabled) !important;
background-color: var(--bs-btn-disabled-bg);
}
.bg-night, body.theme-night .fc-toolbar-chunk .btn.btn-primary {
background-color: #44475a;
--bs-btn-disabled-bg: #44475a;
color: #eee8d5;
background-color: var(--color-night-dark-blue);
--bs-btn-disabled-bg: var(--color-night-dark-blue);
color: var(--color-night-text-dark-bg);
}
.fc-toolbar-chunk .btn.btn-primary {
@ -936,210 +995,210 @@ div#navSrvContainer::-webkit-scrollbar-thumb {
}
.bg-red-outline {
border-color: #F44336;
border-color: var(--color-red);
border-style: solid;
outline: #F44336 solid 1px;
outline: var(--color-red) solid 1px;
}
.bg-pink-outline {
border-color: #E91E63;
border-color: var(--color-pink);
border-style: solid;
outline: #E91E63 solid 1px;
outline: var(--color-pink) solid 1px;
}
.bg-purple-outline {
border-color: #9C27B0;
border-color: var(--color-purple);
border-style: solid;
outline: #9C27B0 solid 1px;
outline: var(--color-purple) solid 1px;
}
.bg-deep-purple-outline {
border-color: #673AB7;
border-color: var(--color-deep-purple);
border-style: solid;
outline: #673AB7 solid 1px;
outline: var(--color-deep-purple) solid 1px;
}
.bg-indigo-outline {
border-color: #3F51B5;
border-color: var(--color-indigo);
border-style: solid;
outline: #3F51B5 solid 1px;
outline: var(--color-indigo) solid 1px;
}
.bg-blue-outline {
border-color: #2196F3;
border-color: var(--color-blue);
border-style: solid;
outline: #2196F3 solid 1px;
outline: var(--color-blue) solid 1px;
}
.bg-light-blue-outline {
border-color: #03A9F4;
border-color: var(--color-light-blue);
border-style: solid;
outline: #03A9F4 solid 1px;
outline: var(--color-light-blue) solid 1px;
}
.bg-cyan-outline {
border-color: #00BCD4;
border-color: var(--color-cyan);
border-style: solid;
outline: #00BCD4 solid 1px;
outline: var(--color-cyan) solid 1px;
}
.bg-teal-outline {
border-color: #009688;
border-color: var(--color-teal);
border-style: solid;
border-width: 3px;
outline: #009688 solid 1px;
outline: var(--color-teal) solid 1px;
}
.bg-green-outline {
border-color: #4CAF50;
border-color: var(--color-green);
border-style: solid;
outline: #4CAF50 solid 1px;
outline: var(--color-green) solid 1px;
}
.bg-light-green-outline {
border-color: #8BC34A;
border-color: var(--color-light-green);
border-style: solid;
outline: #8BC34A solid 1px;
outline: var(--color-light-green) solid 1px;
}
.bg-lime-outline {
border-color: #CDDC39;
border-color: var(--color-lime);
border-style: solid;
outline: #CDDC39 solid 1px;
outline: var(--color-lime) solid 1px;
}
.bg-yellow-outline {
border-color: #ffe821;
border-color: var(--color-yellow);
border-style: solid;
outline: #ffe821 solid 1px;
outline: var(--color-yellow) solid 1px;
}
.bg-amber-outline {
border-color: #FFC107;
border-color: var(--color-amber);
border-style: solid;
outline: #FFC107 solid 1px;
outline: var(--color-amber) solid 1px;
}
.bg-orange-outline {
border-color: #FF9800;
border-color: var(--color-orange);
border-style: solid;
outline: #FF9800 solid 1px;
outline: var(--color-orange) solid 1px;
}
.bg-deep-orange-outline {
border-color: #FF5722;
border-color: var(--color-deep-orange);
border-style: solid;
outline: #FF5722 solid 1px;
outline: var(--color-deep-orange) solid 1px;
}
.bg-brown-outline {
border-color: #795548;
border-color: var(--color-brown);
border-style: solid;
outline: #795548 solid 1px;
outline: var(--color-brown) solid 1px;
}
.bg-grey-outline {
border-color: #9E9E9E;
border-color: var(--color-grey);
border-style: solid;
outline: #9E9E9E solid 1px;
outline: var(--color-grey) solid 1px;
}
.bg-blue-grey-outline {
border-color: #607D8B;
border-color: var(--color-blue-grey);
border-style: solid;
outline: #607D8B solid 1px;
outline: var(--color-blue-grey) solid 1px;
}
.bg-black-outline {
border-color: #555555;
border-color: var(--color-black);
border-style: solid;
outline: #555555 solid 1px;
outline: var(--color-black) solid 1px;
}
.bg-plan-outline {
border-color: #368F17;
border-color: var(--color-plan);
border-style: solid;
outline: #368F17 solid 1px;
outline: var(--color-plan) solid 1px;
}
.col-red {
color: #F44336;
color: var(--color-red);
}
.col-pink {
color: #E91E63;
color: var(--color-pink);
}
.col-purple {
color: #9C27B0;
color: var(--color-purple);
}
.col-deep-purple {
color: #673AB7;
color: var(--color-deep-purple);
}
.col-indigo {
color: #3F51B5;
color: var(--color-indigo);
}
.col-blue {
color: #2196F3;
color: var(--color-blue);
}
.col-light-blue {
color: #03A9F4;
color: var(--color-light-blue);
}
.col-cyan {
color: #00BCD4;
color: var(--color-cyan);
}
.col-teal {
color: #009688;
color: var(--color-teal);
}
.col-green {
color: #4CAF50;
color: var(--color-green);
}
.col-light-green {
color: #8BC34A;
color: var(--color-light-green);
}
.col-lime {
color: #CDDC39;
color: var(--color-lime);
}
.col-yellow {
color: #ffe821;
color: var(--color-yellow);
}
.col-amber {
color: #FFC107;
color: var(--color-amber);
}
.col-orange {
color: #FF9800;
color: var(--color-orange);
}
.col-deep-orange {
color: #FF5722;
color: var(--color-deep-orange);
}
.col-brown {
color: #795548;
color: var(--color-brown);
}
.col-grey {
color: #9E9E9E;
color: var(--color-grey);
}
.col-blue-grey {
color: #607D8B;
color: var(--color-blue-grey);
}
.col-black {
color: #555555;
color: var(--color-black);
}
.col-white {
@ -1147,7 +1206,11 @@ div#navSrvContainer::-webkit-scrollbar-thumb {
}
.col-plan {
color: #368F17;
color: var(--color-plan);
}
.col-theme {
color: var(--color-theme);
}
/* Minecraft color codes */
@ -1184,7 +1247,7 @@ div#navSrvContainer::-webkit-scrollbar-thumb {
}
.darkgray {
color: #555555;
color: var(--color-black);
}
.blue {
@ -1355,4 +1418,10 @@ button, input[type="submit"], input[type="reset"] {
ul.filters {
list-style: none;
padding: 0;
}
#wrapper {
display: flex;
min-height: 100vh;
background-image: linear-gradient(to right, var(--color-theme) 0%, var(--color-theme) 14rem, #f8f9fc 14.01rem, #f8f9fc 100%);
}

View File

@ -164,40 +164,31 @@ export const withReducedSaturation = hex => {
return 'hsl(' + h * 360 + ',' + s * 100 * saturationReduction + '%,' + l * 95 + '%)';
}
const nightColors = {
yellow: "#eee8d5",
black: "#282a36",
darkBlue: "#44475a",
blue: "#6272a4",
greyBlue: "#646e8c",
darkGreyBlue: "#606270"
}
const createNightModeColorCss = () => {
return getColors()
return ':root {' + getColors()
.filter(color => color.name !== 'white' && color.name !== 'black' && color.name !== 'plan')
.map(color => {
const desaturatedColor = withReducedSaturation(color.hex);
return `.bg-${color.name}{background-color: ${desaturatedColor} !important;color: ${nightColors.yellow};}` +
`.bg-${color.name}-outline{outline-color: ${desaturatedColor};border-color: ${desaturatedColor};}` +
`.col-${color.name}{color: ${desaturatedColor} !important;}`
}).join('');
return `--color-${color.name}: ${desaturatedColor} !important;`
}).join('') + '}';
}
export const createNightModeCss = () => {
return `#content-wrapper {background-color:${nightColors.black}!important;}` +
`body,.btn,.bg-transparent-light {color: ${nightColors.yellow};}` +
`.card,.bg-white,.modal-content,.page-loader,.nav-tabs .nav-link:hover,.nav-tabs,hr,form .btn, .btn-outline-secondary{background-color:${nightColors.darkBlue}!important;border-color:${nightColors.blue}!important;}` +
return `#content-wrapper {background-color:var(--color-night-black)!important;}` +
`#wrapper {background-image: linear-gradient(to right, var(--color-night-dark-blue) 0%, var(--color-night-dark-blue) 14rem, var(--color-night-black) 14.01rem, var(--color-night-black) 100%);}` +
`body,.btn,.bg-transparent-light {color: var(--color-night-text-dark-bg);}` +
`.card,.bg-white,.modal-content,.page-loader,.nav-tabs .nav-link:hover,.nav-tabs,hr,form .btn, .btn-outline-secondary{background-color:var(--color-night-dark-blue)!important;border-color:var(--color-night-blue)!important;}` +
`.bg-white.collapse-inner {border:1px solid;}` +
`.card-header {background-color:${nightColors.darkBlue};border-color:${nightColors.blue};}` +
`#content,.col-black,.text-gray-900,.text-gray-800,.collapse-item,.modal-title,.modal-body,.page-loader,.fc-title,.fc-time,pre,.table-dark,input::placeholder{color:${nightColors.yellow} !important;}` +
`.collapse-item:hover,.nav-link.active {background-color: ${nightColors.darkGreyBlue} !important;}` +
`.nav-tabs .nav-link.active {background-color: ${nightColors.darkBlue} !important;border-color:${nightColors.blue} ${nightColors.blue} ${nightColors.darkBlue} !important;}` +
`.fc-today {background:${nightColors.greyBlue} !important}` +
`.fc-popover-body,.fc-popover-header{background-color: ${nightColors.darkBlue} !important;color: ${nightColors.yellow} !important;}` +
`select,input,.dataTables_paginate .page-item:not(.active) a,.input-group-text,.input-group-text > * {background-color:${nightColors.darkBlue} !important;border-color:${nightColors.blue} !important;color: ${nightColors.yellow} !important;}` +
`.topbar-divider,.fc td,.fc tr,.fc th, .fc table, .modal-header,.modal-body,.modal-footer{border-color:${nightColors.blue} !important;}` +
`.fc a{color:${nightColors.yellow} !important;}` +
`.card-header {background-color:var(--color-night-dark-blue);border-color:var(--color-night-blue);}` +
`#content,.col-black,.text-gray-900,.text-gray-800,.collapse-item,.modal-title,.modal-body,.page-loader,.fc-title,.fc-time,pre,.table-dark,input::placeholder{color:var(--color-night-text-dark-bg) !important;}` +
`.collapse-item:hover,.nav-link.active {background-color: var(--color-night-dark-grey-blue) !important;}` +
`.nav-tabs .nav-link.active {background-color: var(--color-night-dark-blue) !important;border-color:var(--color-night-blue) var(--color-night-blue) var(--color-night-dark-blue) !important;}` +
`.fc-today {background:var(--color-night-grey-blue) !important}` +
`.fc-popover-body,.fc-popover-header{background-color: var(--color-night-dark-blue) !important;color: var(--color-night-text-dark-bg) !important;}` +
`select,input,.dataTables_paginate .page-item:not(.active) a,.input-group-text,.input-group-text > * {background-color:var(--color-night-dark-blue) !important;border-color:var(--color-night-blue) !important;color: var(--color-night-text-dark-bg) !important;}` +
`.topbar-divider,.fc td,.fc tr,.fc th, .fc table, .modal-header,.modal-body,.modal-footer{border-color:var(--color-night-blue) !important;}` +
`.fc a{color:var(--color-night-text-dark-bg) !important;}` +
`.fc-button{ background-color: ${withReducedSaturation(colorMap.PLAN.hex)} !important;}` +
`.loader{border: 4px solid var(--color-plan); background-color: var(--color-plan);}` +
createNightModeColorCss()
}

View File

@ -1,5 +1,4 @@
import React from 'react';
import {NightModeCss} from "../../hooks/themeHook";
import Sidebar from "../../components/navigation/Sidebar";
import Header from "../../components/navigation/Header";
import ErrorView from "../ErrorView";
@ -9,8 +8,7 @@ const ErrorPage = ({error}) => {
return (
<>
<NightModeCss/>
<Sidebar items={[]} showBackButton={true}/>
<Sidebar page={'Error occurred'} items={[]}/>
<div className="d-flex flex-column" id="content-wrapper">
<Header page={error.title ? error.title : 'Unexpected error occurred'} hideUpdater/>
<div id="content" style={{display: 'flex'}}>

View File

@ -1,5 +1,4 @@
import React from 'react';
import {NightModeCss} from "../../hooks/themeHook";
import Sidebar from "../../components/navigation/Sidebar";
import Header from "../../components/navigation/Header";
import ColorSelectorModal from "../../components/modal/ColorSelectorModal";
@ -18,10 +17,9 @@ const ErrorsPage = () => {
return (
<>
<NightModeCss/>
<Sidebar items={[]} showBackButton={true}/>
<Sidebar page={'Errors'} items={[]}/>
<div className="d-flex flex-column" id="content-wrapper">
<Header page={<><FontAwesomeIcon icon={faBug}/> Error Logs</>}/>
<Header page={<><FontAwesomeIcon icon={faBug}/> Error Logs</>} hideUpdater/>
<div id="content" style={{display: 'flex'}}>
<main className="container-fluid mt-4">
<Card>

View File

@ -65,7 +65,7 @@ const LoginForm = ({login}) => {
id="inputPassword" placeholder={t('html.login.password')} type="password"
value={password} onChange={event => setPassword(event.target.value)}/>
</div>
<button className="btn bg-plan btn-user w-100" id="login-button" onClick={onLogin}>
<button className="btn bg-theme btn-user w-100" id="login-button" onClick={onLogin}>
{t('html.login.login')}
</button>
</form>
@ -78,7 +78,7 @@ const ColorChooserButton = () => {
return (
<div className='text-center'>
<button className="btn col-plan" onClick={toggleColorChooser}
<button className="btn col-theme" onClick={toggleColorChooser}
title={t('html.label.themeSelect')}>
<Fa icon={faPalette}/>
</button>
@ -90,7 +90,7 @@ const ForgotPasswordButton = ({onClick}) => {
return (
<div className='text-center'>
<button className='col-plan small' onClick={onClick}>{t('html.login.forgotPassword')}</button>
<button className='col-theme small' onClick={onClick}>{t('html.login.forgotPassword')}</button>
</div>
)
}
@ -100,7 +100,7 @@ const CreateAccountLink = () => {
return (
<div className='text-center'>
<Link to='/register' className='col-plan small'>{t('html.login.register')}</Link>
<Link to='/register' className='col-theme small'>{t('html.login.register')}</Link>
</div>
)
}
@ -132,7 +132,7 @@ const LoginPage = () => {
[setForgotPasswordModalOpen, forgotPasswordModalOpen])
useEffect(() => {
document.body.classList.add("bg-plan", "plan-bg-gradient");
document.body.classList.add("bg-theme", "plan-bg-gradient");
const urlParams = new URLSearchParams(window.location.search);
const cameFrom = urlParams.get('from');
@ -142,7 +142,7 @@ const LoginPage = () => {
if (registerSuccess) setSuccessMessage(t('html.register.success'))
return () => {
document.body.classList.remove("bg-plan", "plan-bg-gradient");
document.body.classList.remove("bg-theme", "plan-bg-gradient");
}
}, [setRedirectTo, setSuccessMessage, t])

View File

@ -16,7 +16,6 @@ import {
faUsers
} from "@fortawesome/free-solid-svg-icons";
import {useAuth} from "../../hooks/authenticationHook";
import {NightModeCss} from "../../hooks/themeHook";
import Sidebar from "../../components/navigation/Sidebar";
import Header from "../../components/navigation/Header";
import ColorSelectorModal from "../../components/modal/ColorSelectorModal";
@ -39,6 +38,7 @@ const NetworkSidebar = () => {
const items = [
{name: 'html.label.networkOverview', icon: faInfoCircle, href: "overview"},
{},
{name: 'html.label.information'},
{
name: 'html.label.servers',
icon: faServer,
@ -52,14 +52,16 @@ const NetworkSidebar = () => {
{name: 'html.label.sessions', icon: faCalendarCheck, href: "sessions"},
staticSite ? undefined : {name: 'html.label.performance', icon: faCogs, href: "performance"},
{},
...servers.map(server => {
return {
name: server.serverName,
icon: faServer,
href: "/server/" + server.serverUUID,
color: 'light-green'
}
})
...servers
.filter(server => !server.proxy)
.map(server => {
return {
name: server.serverName,
icon: faServer,
href: "/server/" + server.serverUUID,
color: 'light-green'
}
})
]
},
{
@ -108,7 +110,7 @@ const NetworkSidebar = () => {
}, [t, i18n, extensionData, setSidebarItems, networkMetadata])
return (
<Sidebar items={sidebarItems} showBackButton={false}/>
<Sidebar items={sidebarItems}/>
)
}
@ -124,7 +126,6 @@ const ServerPage = () => {
return (
<>
<NightModeCss/>
<ServerExtensionContextProvider identifier={serverUUID}>
<NetworkSidebar/>
<div className="d-flex flex-column" id="content-wrapper">

View File

@ -2,10 +2,8 @@ import React, {useEffect} from "react";
import Sidebar from "../../components/navigation/Sidebar";
import {Outlet, useOutletContext, useParams} from "react-router-dom";
import ColorSelectorModal from "../../components/modal/ColorSelectorModal";
import {NightModeCss} from "../../hooks/themeHook";
import {fetchPlayer} from "../../service/playerService";
import {faCampground, faCubes, faInfoCircle, faNetworkWired} from "@fortawesome/free-solid-svg-icons";
import {useAuth} from "../../hooks/authenticationHook";
import Header from "../../components/navigation/Header";
import {useNavigation} from "../../hooks/navigationHook";
import {useTranslation} from "react-i18next";
@ -48,15 +46,11 @@ const PlayerPage = () => {
finishUpdate(player.timestamp, player.timestamp_f);
}, [player, t, i18n, finishUpdate, setSidebarItems])
const {hasPermissionOtherThan} = useAuth();
const showBackButton = hasPermissionOtherThan('page.player.self');
if (loadingError) return <ErrorPage error={loadingError}/>;
return player ? (
<>
<NightModeCss/>
<Sidebar items={sidebarItems} showBackButton={showBackButton}/>
<Sidebar page={player.info.name} items={sidebarItems}/>
<div className="d-flex flex-column" id="content-wrapper">
<Header page={player.info.name} tab={currentTab}/>
<div id="content" style={{display: 'flex'}}>
@ -70,7 +64,6 @@ const PlayerPage = () => {
</div>
</>
) : <>
<NightModeCss/>
<div className="page-loader">
<div className="loader-container">
<span className="loader"/>

View File

@ -3,7 +3,6 @@ import {useTranslation} from "react-i18next";
import {Outlet} from "react-router-dom";
import {useNavigation} from "../../hooks/navigationHook";
import {faSearch} from "@fortawesome/free-solid-svg-icons";
import {NightModeCss} from "../../hooks/themeHook";
import Sidebar from "../../components/navigation/Sidebar";
import Header from "../../components/navigation/Header";
import ColorSelectorModal from "../../components/modal/ColorSelectorModal";
@ -13,12 +12,10 @@ import {staticSite} from "../../service/backendConfiguration";
const PlayersPage = () => {
const {t, i18n} = useTranslation();
const {isProxy, serverName} = useMetadata();
const {isProxy, networkName, serverName} = useMetadata();
const [error] = useState(undefined);
const {sidebarItems, setSidebarItems} = useNavigation();
const {currentTab, setCurrentTab} = useNavigation();
const {sidebarItems, setSidebarItems, currentTab, setCurrentTab} = useNavigation();
useEffect(() => {
const items = staticSite ? [] : [
@ -31,16 +28,12 @@ const PlayersPage = () => {
setCurrentTab('html.label.players')
}, [t, i18n, setCurrentTab, setSidebarItems])
// const {authRequired, user} = useAuth();
const showBackButton = true; // TODO
if (error) return <ErrorPage error={error}/>;
const displayedServerName = !isProxy && serverName && serverName.startsWith('Server') ? "Plan" : serverName;
const displayedServerName = isProxy ? networkName : (serverName && serverName.startsWith('Server') ? "Plan" : serverName);
return (
<>
<NightModeCss/>
<Sidebar items={sidebarItems} showBackButton={showBackButton}/>
<Sidebar items={sidebarItems}/>
<div className="d-flex flex-column" id="content-wrapper">
<Header page={displayedServerName} tab={currentTab}/>
<div id="content" style={{display: 'flex'}}>

View File

@ -3,7 +3,6 @@ import {useTranslation} from "react-i18next";
import {Outlet} from "react-router-dom";
import {useNavigation} from "../../hooks/navigationHook";
import {faUndo} from "@fortawesome/free-solid-svg-icons";
import {NightModeCss} from "../../hooks/themeHook";
import Sidebar from "../../components/navigation/Sidebar";
import Header from "../../components/navigation/Header";
import ColorSelectorModal from "../../components/modal/ColorSelectorModal";
@ -13,7 +12,7 @@ import {QueryResultContextProvider} from "../../hooks/queryResultContext";
const QueryPage = () => {
const {t, i18n} = useTranslation();
const {isProxy, serverName} = useMetadata();
const {isProxy, networkName, serverName} = useMetadata();
const [error] = useState(undefined);
const {sidebarItems, setSidebarItems} = useNavigation();
@ -31,16 +30,13 @@ const QueryPage = () => {
setCurrentTab('html.query.title.text');
}, [t, i18n, setCurrentTab, setSidebarItems])
const showBackButton = true;
if (error) return <ErrorPage error={error}/>;
const displayedServerName = !isProxy && serverName && serverName.startsWith('Server') ? "Plan" : serverName;
const displayedServerName = isProxy ? networkName : (serverName && serverName.startsWith('Server') ? "Plan" : serverName);
return (
<>
<NightModeCss/>
<QueryResultContextProvider>
<Sidebar items={sidebarItems} showBackButton={showBackButton}/>
<Sidebar items={sidebarItems}/>
<div className="d-flex flex-column" id="content-wrapper">
<Header page={displayedServerName} tab={currentTab} hideUpdater/>
<div id="content" style={{display: 'flex'}}>

View File

@ -66,7 +66,7 @@ const RegisterForm = ({register}) => {
value={password} onChange={event => setPassword(event.target.value)}/>
<div className={"form-text"}>{t('html.register.passwordTip')}</div>
</div>
<button className="btn bg-plan btn-user w-100" id="register-button" onClick={onRegister}>
<button className="btn bg-theme btn-user w-100" id="register-button" onClick={onRegister}>
{t('html.register.register')}
</button>
</form>
@ -79,7 +79,7 @@ const ColorChooserButton = () => {
return (
<div className='text-center'>
<button className="btn col-plan" onClick={toggleColorChooser}
<button className="btn col-theme" onClick={toggleColorChooser}
title={t('html.label.themeSelect')}>
<Fa icon={faPalette}/>
</button>
@ -92,7 +92,7 @@ const LoginLink = () => {
return (
<div className='text-center'>
<Link to='/login' className='col-plan small'>{t('html.register.login')}</Link>
<Link to='/login' className='col-theme small'>{t('html.register.login')}</Link>
</div>
)
}
@ -111,10 +111,10 @@ const RegisterPage = () => {
[setFinalizeRegistrationModalOpen, finalizeRegistrationModalOpen])
useEffect(() => {
document.body.classList.add("bg-plan", "plan-bg-gradient");
document.body.classList.add("bg-theme", "plan-bg-gradient");
return () => {
document.body.classList.remove("bg-plan", "plan-bg-gradient");
document.body.classList.remove("bg-theme", "plan-bg-gradient");
}
}, []);

View File

@ -16,7 +16,6 @@ import {
faUsers
} from "@fortawesome/free-solid-svg-icons";
import {useAuth} from "../../hooks/authenticationHook";
import {NightModeCss} from "../../hooks/themeHook";
import Sidebar from "../../components/navigation/Sidebar";
import Header from "../../components/navigation/Header";
import ColorSelectorModal from "../../components/modal/ColorSelectorModal";
@ -35,11 +34,6 @@ const ServerSidebar = () => {
const {t, i18n} = useTranslation();
const {sidebarItems, setSidebarItems} = useNavigation();
const {extensionData} = useServerExtensionContext();
const {authRequired, loggedIn, user} = useAuth();
const {isProxy} = useMetadata();
const showBackButton = isProxy
&& (!authRequired || (loggedIn && user.permissions.filter(perm => perm !== 'page.network').length));
useEffect(() => {
const items = [
@ -107,14 +101,14 @@ const ServerSidebar = () => {
}, [t, i18n, extensionData, setSidebarItems])
return (
<Sidebar items={sidebarItems} showBackButton={showBackButton}/>
<Sidebar items={sidebarItems}/>
)
}
const ServerPage = () => {
const {t} = useTranslation();
const {identifier} = useParams();
const {isProxy, serverName} = useMetadata();
const {isProxy, serverName, networkMetadata} = useMetadata();
const {
data: serverIdentity,
@ -133,7 +127,8 @@ const ServerPage = () => {
}
if (isProxy) {
return identifier;
const fromMetadata = networkMetadata?.servers?.find(server => server.serverUUID === identifier);
return fromMetadata ? fromMetadata.serverName : identifier;
} else {
return serverName && serverName.startsWith('Server') ? "Plan" : serverName
}
@ -152,7 +147,6 @@ const ServerPage = () => {
return (
<>
<NightModeCss/>
<ServerExtensionContextProvider identifier={identifier}>
<ServerSidebar/>
<div className="d-flex flex-column" id="content-wrapper">