Skip to content

Commit

Permalink
Code review; Use Suspense
Browse files Browse the repository at this point in the history
  • Loading branch information
l7ssha committed Dec 11, 2024
1 parent 8ef5619 commit 637f35a
Show file tree
Hide file tree
Showing 11 changed files with 293 additions and 261 deletions.
8 changes: 4 additions & 4 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
"@testing-library/user-event": "^13.2.1",
"@types/jest": "^27.0.1",
"@types/node": "^16.7.13",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"axios": "^1.7.9",
"date-fns": "^4.1.0",
"jwt-decode": "^4.0.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-jwt": "^1.2.2",
"react-router-dom": "^7.0.2",
"react-scripts": "5.0.1",
Expand Down
16 changes: 5 additions & 11 deletions frontend/src/component/NavigationBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,8 @@ export default function NavigationBar() {
const userPermissions = getCurrentUserPermissions();

const [anchorElUser, setAnchorElUser] = React.useState<null | HTMLElement>(null);
const handleOpenUserMenu = (event: React.MouseEvent<HTMLElement>) => {
setAnchorElUser(event.currentTarget);
};
const handleCloseUserMenu = () => {
setAnchorElUser(null);
const toggleUserMenu = (event?: React.MouseEvent<HTMLElement>) => {
setAnchorElUser(event?.currentTarget ?? null);
};

const logoutAndRedirect = () => {
Expand All @@ -40,14 +37,11 @@ export default function NavigationBar() {

let userElement = <Button href={discordLoginUri}>Login</Button>;
if (userLoggedIn) {
const user = getUser();
if (user === null) {
throw new Error("User cannot possibly be null");
}
const user = getUser()!;

userElement = <Box sx={{flexGrow: 0}}>
<Tooltip title="Open settings">
<IconButton onClick={handleOpenUserMenu} sx={{p: 0}}>
<IconButton onClick={toggleUserMenu} sx={{p: 0}}>
<Typography sx={{color: 'white', fontSize: 20}} marginInlineEnd="0.5em">{user.name}</Typography>
<Avatar alt="User's avatar" src={getUserAvatar(user.id, user.avatar as string)}/>
</IconButton>
Expand All @@ -66,7 +60,7 @@ export default function NavigationBar() {
horizontal: 'right',
}}
open={Boolean(anchorElUser)}
onClose={handleCloseUserMenu}
onClose={() => toggleUserMenu()}
>
<MenuItem key="color-mode">
<FormControl>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/component/ProtectedRoute.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ export const ProtectedRoute = (props: Props) => {
);
}

return <div children={props.children} />
return <div>{props.children}</div>;
};
4 changes: 2 additions & 2 deletions frontend/src/component/botInfo/BotInfoElement.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {Box, Grid2, Paper, Typography} from "@mui/material";
import React from "react";

type BotInfoElementProps = {
interface BotInfoElementProps {
name: string,
value: string|number|undefined,
size?: number,
};
}

export function BotInfoElement({name, value, size = 3}: BotInfoElementProps) {
return (
Expand Down
12 changes: 6 additions & 6 deletions frontend/src/component/botInfo/BotInfoGrid.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import {Container, Grid2, Paper, Typography} from "@mui/material";
import React from "react";
import {BotInfo} from "../../service/useApi";
import React, {use} from "react";
import {BotInfo, fetchBotInfo} from "../../service/api";
import {BotInfoElement} from "./BotInfoElement";
import {parseISO, formatRelative} from "date-fns";

type BotInfoGridProps = {
botInfoStats: BotInfo,
};
const botInfoStatusPromise = fetchBotInfo();

export function BotInfoGrid() {
const botInfoStats = use(botInfoStatusPromise);

export function BotInfoGrid({botInfoStats}: BotInfoGridProps) {
const docsUpdatedAt = formatRelative(parseISO(botInfoStats.docsUpdate), new Date());
const uptime = formatRelative(parseISO(botInfoStats.uptime), new Date());

Expand Down
2 changes: 1 addition & 1 deletion frontend/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";

export type Props = {
export interface Props {
children: string | React.JSX.Element | React.JSX.Element[]
}

Expand Down
17 changes: 4 additions & 13 deletions frontend/src/page/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
import React, {useEffect, useState} from 'react';
import {Suspense} from 'react';

import {Base} from "../component/Base";
import {BotInfo, useApi} from "../service/useApi";
import {BotInfoGrid} from "../component/botInfo/BotInfoGrid";

export default function Home() {
const {fetchBotInfo} = useApi();

const [stats, setStats] = useState<BotInfo|null>();

useEffect(() => {
fetchBotInfo().then(result => {
setStats(result);
});
}, []);

return (
<Base>
{stats != null ? <BotInfoGrid botInfoStats={stats!} /> : <div>Loading...</div>}
<Suspense fallback={<div>Loading...</div>}>
<BotInfoGrid />
</Suspense>
</Base>
);
}
27 changes: 13 additions & 14 deletions frontend/src/page/admin/Guilds.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, {useEffect, useState} from 'react';
import React, {Suspense, use, useEffect, useState} from 'react';
import {Base} from "../../component/Base";
import {Guild, useApi} from "../../service/useApi";
import {fetchGuilds, Guild} from "../../service/api";
import {DataGrid, GridColDef} from "@mui/x-data-grid";
import {Alert, Avatar, Stack, Typography} from "@mui/material";
import {getGuildIcon} from "../../constants";
Expand Down Expand Up @@ -54,22 +54,21 @@ function mapApiDataToRows(guilds: Guild[]): GuildRowDef[] {
});
}

export default function Guilds() {
const [rows, setRows] = useState<GuildRowDef[]>([]);
const {fetchGuilds} = useApi();
const guildDataPromise = fetchGuilds().then(guilds => {
return mapApiDataToRows(guilds);
});

useEffect(() => {
fetchGuilds().then(guilds => {
setRows(mapApiDataToRows(guilds));
});
}, []);
export default function Guilds() {
const rows = use(guildDataPromise);

return (
<Base>
<Stack direction="column" spacing={1}>
<Alert severity="error">Table represents cached data, that is available for bot at the moment.</Alert>
<DataGrid rows={rows} columns={columns}/>
</Stack>
<Suspense fallback={<div>Loading...</div>}>
<Stack direction="column" spacing={1}>
<Alert severity="error">Table represents cached data, that is available for bot at the moment.</Alert>
<DataGrid rows={rows} columns={columns}/>
</Stack>
</Suspense>
</Base>
);
}
18 changes: 7 additions & 11 deletions frontend/src/service/useApi.ts → frontend/src/service/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,14 @@ export type Guild = {
tagsCount: number,
};

export class Api {
async fetchBotInfo(): Promise<BotInfo> {
const response = await axiosAuthenticated.get<BotInfo>("/api/server-info", {data: {useAuth: false}});
export async function fetchBotInfo(): Promise<BotInfo> {
const response = await axiosAuthenticated.get<BotInfo>("/api/server-info", {data: {useAuth: false}});

return response.data;
}
return response.data;
}

async fetchGuilds(): Promise<Guild[]> {
const response = await axiosAuthenticated.get<Guild[]>("/api/guilds", {data: {useAuth: true}})
export async function fetchGuilds(): Promise<Guild[]> {
const response = await axiosAuthenticated.get<Guild[]>("/api/guilds", {data: {useAuth: true}})

return response.data;
}
return response.data;
}

export const useApi = () => new Api();
9 changes: 3 additions & 6 deletions frontend/src/service/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,7 @@ export function getUser(): UserData|null {

export function isLoggedIn(): boolean {
const tokenPayload = getTokenPayload();
if (tokenPayload == null) {
return false;
}

if (tokenPayload.exp == null) {
if (!tokenPayload?.exp) {
return false;
}

Expand All @@ -72,7 +68,8 @@ export function isLoggedIn(): boolean {
return false;

}
return true

return true;
}

export function setAuthData(authData: AuthData) {
Expand Down
Loading

0 comments on commit 637f35a

Please sign in to comment.