ui tweaks. add FAQ section. move filters to submenu

This commit is contained in:
calli
2025-04-25 09:38:10 +03:00
parent a1f682e9fc
commit de49595f55
8 changed files with 234 additions and 130 deletions

View File

@@ -1,21 +0,0 @@
import { SessionContext } from "@/app/context/Context";
import { Button, Tooltip } from "@mui/material";
import { useContext } from "react";
export const AlertModeButton = () => {
const { alertMode, toggleAlertMode } = useContext(SessionContext);
return (
<Tooltip title="Toggle alert mode to show only accounts and planets that need action.">
<Button
style={{
backgroundColor: alertMode
? "rgba(144, 202, 249, 0.08)"
: "inherit",
}}
onClick={toggleAlertMode}
>
Alert mode
</Button>
</Tooltip>
);
};

View File

@@ -12,20 +12,25 @@ import * as React from "react";
import { DowloadButton } from "../Backup/DowloadButton"; import { DowloadButton } from "../Backup/DowloadButton";
import { UploadButton } from "../Backup/UploadButton"; import { UploadButton } from "../Backup/UploadButton";
import { CCPButton } from "../CCP/CCPButton"; import { CCPButton } from "../CCP/CCPButton";
import { CompactModeButton } from "../CompactModeButton/CompactModeButton";
import { DiscordButton } from "../Discord/DiscordButton"; import { DiscordButton } from "../Discord/DiscordButton";
import { GitHubButton } from "../Github/GitHubButton"; import { GitHubButton } from "../Github/GitHubButton";
import { LoginButton } from "../Login/LoginButton"; import { LoginButton } from "../Login/LoginButton";
import { PlanModeButton } from "../PlanModeButton/PlanModeButton";
import { SettingsButton } from "../Settings/SettingsButtons"; import { SettingsButton } from "../Settings/SettingsButtons";
import { AlertModeButton } from "../AlertModeButton/AlertModeButton"; import {
import { SupportButton } from "../SupportButton/SupportButton"; Button,
Dialog,
DialogTitle,
DialogContent,
DialogContentText,
DialogActions,
} from "@mui/material";
import { useState } from "react";
function ResponsiveAppBar() { function ResponsiveAppBar() {
const [anchorElNav, setAnchorElNav] = React.useState<null | HTMLElement>( const [anchorElNav, setAnchorElNav] = React.useState<null | HTMLElement>(
null, null,
); );
const [faqOpen, setFaqOpen] = useState(false);
const handleOpenNavMenu = (event: React.MouseEvent<HTMLElement>) => { const handleOpenNavMenu = (event: React.MouseEvent<HTMLElement>) => {
setAnchorElNav(event.currentTarget); setAnchorElNav(event.currentTarget);
@@ -102,23 +107,26 @@ function ResponsiveAppBar() {
<MenuItem onClick={handleCloseNavMenu}> <MenuItem onClick={handleCloseNavMenu}>
<GitHubButton /> <GitHubButton />
</MenuItem> </MenuItem>
<MenuItem onClick={handleCloseNavMenu}>
<CCPButton />
</MenuItem>
<MenuItem onClick={handleCloseNavMenu}>
<SupportButton />
</MenuItem>
<MenuItem onClick={handleCloseNavMenu}> <MenuItem onClick={handleCloseNavMenu}>
<SettingsButton /> <SettingsButton />
</MenuItem> </MenuItem>
<MenuItem onClick={handleCloseNavMenu}> <MenuItem
<CompactModeButton /> onClick={() => {
handleCloseNavMenu();
setFaqOpen(true);
}}
>
<Button
href=""
style={{ width: "100%" }}
sx={{ color: "white", display: "flex", justifyContent: "flex-start" }}
>
FAQ
</Button>
</MenuItem> </MenuItem>
<MenuItem onClick={handleCloseNavMenu}> <MenuItem onClick={handleCloseNavMenu}>
<PlanModeButton /> <CCPButton />
</MenuItem>
<MenuItem onClick={handleCloseNavMenu}>
<AlertModeButton />
</MenuItem> </MenuItem>
</Menu> </Menu>
</Box> </Box>
@@ -146,7 +154,7 @@ function ResponsiveAppBar() {
flexGrow: 1, flexGrow: 1,
display: { xs: "none", md: "flex" }, display: { xs: "none", md: "flex" },
alignItems: "center", alignItems: "center",
gap: "0.2rem" gap: "0.2rem",
}} }}
> >
<LoginButton /> <LoginButton />
@@ -154,15 +162,132 @@ function ResponsiveAppBar() {
<UploadButton /> <UploadButton />
<DiscordButton /> <DiscordButton />
<GitHubButton /> <GitHubButton />
<CCPButton />
<SupportButton />
<SettingsButton /> <SettingsButton />
<CompactModeButton /> <Button onClick={() => setFaqOpen(true)} color="inherit">
<PlanModeButton /> FAQ
<AlertModeButton /> </Button>
<CCPButton />
</Box> </Box>
</Toolbar> </Toolbar>
</Container> </Container>
<Dialog
open={faqOpen}
onClose={() => setFaqOpen(false)}
aria-labelledby="faq-dialog-title"
>
<DialogTitle id="faq-dialog-title">
Frequently Asked Questions
</DialogTitle>
<DialogContent>
<DialogContentText>
<strong>EVE Online Partner Code</strong>
<br />
Consider using my partner code for CCP related purchases to support
this project:
<Button
href=""
style={{ width: "100%" }}
sx={{ color: "white", display: "block" }}
onClick={() => {
navigator.clipboard.writeText("CALLIEVE");
}}
>
CALLIEVE
</Button>{" "}
Click button above to copy to clipboard.
<br />
<br />
<strong>What is this application?</strong>
<br />
This EVE Online Planetary Interaction tool that helps you track and
manage your colonies and production chains. Main usecase is to see
if your extractors are running.
<br />
<br />
<strong>How do I add characters?</strong>
<br />
You can add characters by clicking the &quot;Add Character&quot;
button in the app bar and following the authentication process.
<br />
<br />
<strong>Why don&apos;t my storage numbers add up?</strong>
<br />
EVE Online API (ESI) provides planetary interaction endpoints. These
are updated when you submit changes to planet. For example after an
extractor restart.
<br />
<br />
<strong>What does exclude mean?</strong>
<br />
Exclude means that this planet will not be counted in totals. This
is useful if you have longer production chains where exports of a
planet are consumed by another planet.
<br />
<br />
<strong>How do see my planets production chains?</strong>
<br />
Click on the planet row to open the extraction simulation.
<br />
<br />
<strong>What is Compact Mode?</strong>
<br />
Compact Mode reduces the size of character cards to show more
information at once. You can toggle it in the settings.
<br />
<br />
<strong>What is Alert Mode?</strong>
<br />
Alert mode shows only the planets that have extractors offline and
need attention.
<br />
<br />
<strong>What does off-blanace mean?</strong>
<br />
Off-blanace alert shows up for planets that have two extractors that
are extracting different amount of material. Treshold can be set in
settings. Generally you want to keep this below 1000.
<br />
<br />
<strong>How do I reorder accounts?</strong>
<br />
You can drag and drop account cards to reorder them. The order will
be saved automatically.
<br />
<br />
<strong>How do I add a character to account groups?</strong>
<br />
You can add a character to an account group by clicking the cog on
the character card and typing in the account/group name.
<br />
<br />
<strong>I like icons! Why so much text?</strong>
<br />
Toggle this option in settings.
<br />
<br />
<strong>I like colors! Why your alert colors are so ugly?</strong>
<br />
Change the color scheme in settings.
<br />
<br />
<strong>What does the 3D view do?</strong>
<br />
Nothing. Just made it for fun
<br />
<br />
<strong>Why are planet settings empty?</strong>
<br />
Its a work in progress feature. Plan is to be able to configuer
planet and planet exports to belong to production chains.
<br />
<br />
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={() => setFaqOpen(false)}>Close</Button>
</DialogActions>
</Dialog>
</AppBar> </AppBar>
); );
} }

View File

@@ -1,21 +0,0 @@
import { SessionContext } from "@/app/context/Context";
import { Button, Tooltip } from "@mui/material";
import { useContext } from "react";
export const CompactModeButton = () => {
const { compactMode, toggleCompactMode } = useContext(SessionContext);
return (
<Tooltip title="Toggle compact layout for widescreen">
<Button
style={{
backgroundColor: compactMode
? "rgba(144, 202, 249, 0.08)"
: "inherit",
}}
onClick={toggleCompactMode}
>
Compact mode
</Button>
</Tooltip>
);
};

View File

@@ -6,15 +6,21 @@ import {
ThemeProvider, ThemeProvider,
createTheme, createTheme,
Button, Button,
Tooltip,
} from "@mui/material"; } from "@mui/material";
import { AccountCard } from "./Account/AccountCard"; import { AccountCard } from "./Account/AccountCard";
import { AccessToken } from "@/types"; import { AccessToken } from "@/types";
import { CharacterContext, SessionContext } from "../context/Context"; import { CharacterContext, SessionContext } from "../context/Context";
import ResponsiveAppBar from "./AppBar/AppBar"; import ResponsiveAppBar from "./AppBar/AppBar";
import { Summary } from "./Summary/Summary"; import { Summary } from "./Summary/Summary";
import { DragDropContext, Droppable, Draggable, DropResult } from "@hello-pangea/dnd"; import {
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; DragDropContext,
import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp'; Droppable,
Draggable,
DropResult,
} from "@hello-pangea/dnd";
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp";
interface Grouped { interface Grouped {
[key: string]: AccessToken[]; [key: string]: AccessToken[];
@@ -43,6 +49,7 @@ declare module "@mui/material/styles" {
export const MainGrid = () => { export const MainGrid = () => {
const { characters, updateCharacter } = useContext(CharacterContext); const { characters, updateCharacter } = useContext(CharacterContext);
const { compactMode, toggleCompactMode, alertMode, toggleAlertMode, planMode, togglePlanMode } = useContext(SessionContext);
const [accountOrder, setAccountOrder] = useState<string[]>([]); const [accountOrder, setAccountOrder] = useState<string[]>([]);
const [allCollapsed, setAllCollapsed] = useState(false); const [allCollapsed, setAllCollapsed] = useState(false);
@@ -54,15 +61,19 @@ export const MainGrid = () => {
group[account ?? ""] = group[account ?? ""] ?? []; group[account ?? ""] = group[account ?? ""] ?? [];
group[account ?? ""].push(character); group[account ?? ""].push(character);
return group; return group;
}, {}) }, {}),
); );
const savedOrder = localStorage.getItem('accountOrder'); const savedOrder = localStorage.getItem("accountOrder");
if (savedOrder) { if (savedOrder) {
try { try {
const parsedOrder = JSON.parse(savedOrder); const parsedOrder = JSON.parse(savedOrder);
const validOrder = parsedOrder.filter((account: string) => currentAccounts.includes(account)); const validOrder = parsedOrder.filter((account: string) =>
const newAccounts = currentAccounts.filter(account => !validOrder.includes(account)); currentAccounts.includes(account),
);
const newAccounts = currentAccounts.filter(
(account) => !validOrder.includes(account),
);
setAccountOrder([...validOrder, ...newAccounts]); setAccountOrder([...validOrder, ...newAccounts]);
} catch (e) { } catch (e) {
setAccountOrder(currentAccounts); setAccountOrder(currentAccounts);
@@ -74,7 +85,7 @@ export const MainGrid = () => {
useEffect(() => { useEffect(() => {
if (accountOrder.length > 0) { if (accountOrder.length > 0) {
localStorage.setItem('accountOrder', JSON.stringify(accountOrder)); localStorage.setItem("accountOrder", JSON.stringify(accountOrder));
} }
}, [accountOrder]); }, [accountOrder]);
@@ -85,7 +96,6 @@ export const MainGrid = () => {
return group; return group;
}, {}); }, {});
const { compactMode } = useContext(SessionContext);
const [darkTheme, setDarkTheme] = useState( const [darkTheme, setDarkTheme] = useState(
createTheme({ createTheme({
palette: { palette: {
@@ -138,14 +148,62 @@ export const MainGrid = () => {
<Box sx={{ flexGrow: 1 }}> <Box sx={{ flexGrow: 1 }}>
<ResponsiveAppBar /> <ResponsiveAppBar />
{compactMode ? <></> : <Summary characters={characters} />} {compactMode ? <></> : <Summary characters={characters} />}
<Box sx={{ display: 'flex', justifyContent: 'flex-start', padding: 1 }}> <Box
sx={{
display: "flex",
justifyContent: "flex-start",
padding: 1,
gap: 1,
}}
>
<Button <Button
startIcon={allCollapsed ? <KeyboardArrowDownIcon /> : <KeyboardArrowUpIcon />} startIcon={
allCollapsed ? <KeyboardArrowDownIcon /> : <KeyboardArrowUpIcon />
}
onClick={() => setAllCollapsed(!allCollapsed)} onClick={() => setAllCollapsed(!allCollapsed)}
size="small" size="small"
> >
{allCollapsed ? 'Expand All' : 'Collapse All'} {allCollapsed ? "Expand All" : "Collapse All"}
</Button> </Button>
<Tooltip title="Toggle compact layout for widescreen">
<Button
size="small"
style={{
backgroundColor: compactMode
? "rgba(144, 202, 249, 0.08)"
: "inherit",
}}
onClick={toggleCompactMode}
>
Compact mode
</Button>
</Tooltip>
<Tooltip title="Toggle alert mode to show only accounts and planets that need action.">
<Button
size="small"
style={{
backgroundColor: alertMode
? "rgba(144, 202, 249, 0.08)"
: "inherit",
}}
onClick={toggleAlertMode}
>
Alert mode
</Button>
</Tooltip>
<Tooltip title="Toggle plan mode that show layout for widescreen">
<Button
size="small"
style={{
backgroundColor: planMode
? "rgba(144, 202, 249, 0.08)"
: "inherit",
}}
onClick={togglePlanMode}
>
Plan mode
</Button>
</Tooltip>
</Box> </Box>
<DragDropContextComponent onDragEnd={handleDragEnd}> <DragDropContextComponent onDragEnd={handleDragEnd}>
<DroppableComponent droppableId="accounts"> <DroppableComponent droppableId="accounts">
@@ -153,7 +211,7 @@ export const MainGrid = () => {
<Grid <Grid
container container
spacing={1} spacing={1}
sx={{ padding: 1, width: '100%' }} sx={{ padding: 1, width: "100%" }}
{...provided.droppableProps} {...provided.droppableProps}
ref={provided.innerRef} ref={provided.innerRef}
> >
@@ -172,17 +230,18 @@ export const MainGrid = () => {
{...provided.draggableProps} {...provided.draggableProps}
{...provided.dragHandleProps} {...provided.dragHandleProps}
sx={{ sx={{
'& > *': { "& > *": {
width: '100%', width: "100%",
}, },
}} }}
> >
{groupByAccount[account] && groupByAccount[account].length > 0 && ( {groupByAccount[account] &&
<AccountCard groupByAccount[account].length > 0 && (
characters={groupByAccount[account]} <AccountCard
isCollapsed={allCollapsed} characters={groupByAccount[account]}
/> isCollapsed={allCollapsed}
)} />
)}
</Grid> </Grid>
)} )}
</DraggableComponent> </DraggableComponent>

View File

@@ -1,15 +0,0 @@
import { SessionContext } from "@/app/context/Context";
import { Button, Tooltip } from "@mui/material";
import { useContext } from "react";
export const PlanModeButton = () => {
const { planMode, togglePlanMode } = useContext(SessionContext);
return (
<Tooltip title="Toggle plan mode that show layout for widescreen">
<Button onClick={togglePlanMode} style={{backgroundColor: planMode ? 'rgba(144, 202, 249, 0.08)' : 'inherit'}}>
Plan mode
</Button>
</Tooltip>
);
};

View File

@@ -167,20 +167,20 @@ export const PlanetTableRow = ({
/> />
{amount !== undefined && ( {amount !== undefined && (
<Typography fontSize={theme.custom.smallText} style={{ marginLeft: "5px", flexShrink: 0 }}> <Typography fontSize={theme.custom.smallText} style={{ marginLeft: "5px", flexShrink: 0 }}>
{amount}/h {amount}
</Typography> </Typography>
)} )}
</div> </div>
); );
} }
return ( return (
<div style={{ display: "flex", justifyContent: "space-between", width: "100%" }}> <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", width: "100%" }}>
<Typography fontSize={theme.custom.smallText}> <Typography fontSize={theme.custom.smallText}>
{PI_TYPES_MAP[typeId].name} {PI_TYPES_MAP[typeId].name}
</Typography> </Typography>
{amount !== undefined && ( {amount !== undefined && (
<Typography fontSize={theme.custom.smallText} style={{ marginLeft: "5px", flexShrink: 0 }}> <Typography fontSize={theme.custom.smallText} style={{ marginLeft: "5px", flexShrink: 0 }}>
{amount}/h {amount}
</Typography> </Typography>
)} )}
</div> </div>

View File

@@ -84,8 +84,8 @@ const PlanetaryIteractionTable = ({
</Tooltip> </Tooltip>
</TableCell> </TableCell>
<TableCell width="2%"> <TableCell width="2%">
<Tooltip title="How many units per hour factories are producing"> <Tooltip title="How many units per hour factories are producing on this planet">
<Typography fontSize={theme.custom.smallText}>u/h</Typography> <Typography fontSize={theme.custom.smallText}>uph</Typography>
</Tooltip> </Tooltip>
</TableCell> </TableCell>
<TableCell width="4%" align="right"> <TableCell width="4%" align="right">
@@ -98,7 +98,7 @@ const PlanetaryIteractionTable = ({
<TableCell width="10%"> <TableCell width="10%">
<Tooltip title="Storage facility fill rate"> <Tooltip title="Storage facility fill rate">
<Typography fontSize={theme.custom.smallText}> <Typography fontSize={theme.custom.smallText}>
Storage Fill rate Storage%
</Typography> </Typography>
</Tooltip> </Tooltip>
</TableCell> </TableCell>

View File

@@ -1,23 +0,0 @@
import { Box, Button, Tooltip } from "@mui/material";
export const SupportButton = () => {
return (
<Box>
<Tooltip
title={`
Consider using code 'CALLIEVE' on EVE store checkout to support the project! Click to copy to clipboard ;)
`}
>
<Button
href=""
style={{ width: "100%" }}
sx={{ color: "white", display: "block" }}
onClick={() => {
navigator.clipboard.writeText("CALLIEVE");
}}
>
CALLIEVE
</Button>
</Tooltip>
</Box>
);
};