mirror of
https://github.com/roleypoly/roleypoly.git
synced 2025-06-15 00:59:09 +00:00
Feat/editor category pass2 (#290)
* feat(design-system): add editor skeletons * use css media queries rather than JS media queries * init remake * feat: add basis of toggle atom * finish toggle * use pointer cursor with toggle * sync * feat: add server message in editor * cleanup storybook * add short editor item and data model for categories * chore: fix build by moving jest version downward * chore: remove old category editor * chore: fix EditorCategoryShort index * add editor wiring and styling updates * fix linting issues
This commit is contained in:
parent
a37d481b18
commit
7d681d69d6
48 changed files with 927 additions and 1100 deletions
|
@ -7,6 +7,7 @@ import LandingPage from '../pages/landing';
|
|||
import PickerPage from '../pages/picker';
|
||||
|
||||
const ServersPage = React.lazy(() => import('../pages/servers'));
|
||||
const EditorPage = React.lazy(() => import('../pages/editor'));
|
||||
|
||||
const MachineryNewSession = React.lazy(() => import('../pages/machinery/new-session'));
|
||||
const MachineryLogout = React.lazy(() => import('../pages/machinery/logout'));
|
||||
|
@ -32,6 +33,7 @@ export const AppRouter = () => {
|
|||
<RouteWrapper component={LandingPage} path="/" />
|
||||
<RouteWrapper component={ServersPage} path="/servers" />
|
||||
<RouteWrapper component={PickerPage} path="/s/:serverID" />
|
||||
<RouteWrapper component={EditorPage} path="/s/:serverID/edit" />
|
||||
|
||||
<RouteWrapper component={ErrorPage} path="/error" />
|
||||
<RouteWrapper component={ErrorPage} path="/error/:identity" />
|
||||
|
|
100
packages/web/src/pages/editor.tsx
Normal file
100
packages/web/src/pages/editor.tsx
Normal file
|
@ -0,0 +1,100 @@
|
|||
import { Redirect } from '@reach/router';
|
||||
import { EditorTemplate } from '@roleypoly/design-system/templates/editor';
|
||||
import { GenericLoadingTemplate } from '@roleypoly/design-system/templates/generic-loading';
|
||||
import {
|
||||
GuildDataUpdate,
|
||||
PresentableGuild,
|
||||
UserGuildPermissions,
|
||||
} from '@roleypoly/types';
|
||||
import * as React from 'react';
|
||||
import { useAppShellProps } from '../contexts/app-shell/AppShellContext';
|
||||
import { useRecentGuilds } from '../contexts/recent-guilds/RecentGuildsContext';
|
||||
import { useSessionContext } from '../contexts/session/SessionContext';
|
||||
import { Title } from '../utils/metaTitle';
|
||||
|
||||
type EditorProps = {
|
||||
serverID: string;
|
||||
path: string;
|
||||
};
|
||||
|
||||
const Editor = (props: EditorProps) => {
|
||||
const { serverID } = props;
|
||||
const { session, authedFetch, isAuthenticated } = useSessionContext();
|
||||
const { pushRecentGuild } = useRecentGuilds();
|
||||
const appShellProps = useAppShellProps();
|
||||
|
||||
const [guild, setGuild] = React.useState<PresentableGuild | null | false>(null);
|
||||
const [pending, setPending] = React.useState(false);
|
||||
|
||||
React.useEffect(() => {
|
||||
const fetchGuild = async () => {
|
||||
const response = await authedFetch(`/get-picker-data/${serverID}`);
|
||||
const data = await response.json();
|
||||
|
||||
if (response.status !== 200) {
|
||||
setGuild(false);
|
||||
return;
|
||||
}
|
||||
|
||||
setGuild(data);
|
||||
};
|
||||
|
||||
fetchGuild();
|
||||
}, [serverID, authedFetch]);
|
||||
|
||||
React.useCallback((serverID) => pushRecentGuild(serverID), [pushRecentGuild])(serverID);
|
||||
|
||||
// If the user is not authenticated, redirect to the login page.
|
||||
if (!isAuthenticated) {
|
||||
return <Redirect to={`/auth/login?r=${props.serverID}`} replace />;
|
||||
}
|
||||
|
||||
// If the user is not an admin, they can't edit the guild
|
||||
// so we redirect them to the picker
|
||||
const guildSlug = session?.guilds?.find((guild) => guild.id === serverID);
|
||||
if (guildSlug && guildSlug?.permissionLevel === UserGuildPermissions.User) {
|
||||
return <Redirect to={`/s/${props.serverID}`} replace />;
|
||||
}
|
||||
|
||||
// If the guild isn't loaded, render a loading placeholder
|
||||
if (guild === null) {
|
||||
return <GenericLoadingTemplate />;
|
||||
}
|
||||
|
||||
// If the guild is not found, redirect to the picker page
|
||||
if (guild === false) {
|
||||
return <Redirect to={`/s/${props.serverID}`} replace />;
|
||||
}
|
||||
|
||||
const onGuildChange = async (guild: PresentableGuild) => {
|
||||
if (pending) {
|
||||
return;
|
||||
}
|
||||
|
||||
setPending(true);
|
||||
|
||||
const updatePayload: GuildDataUpdate = {
|
||||
message: guild.data.message,
|
||||
categories: guild.data.categories,
|
||||
};
|
||||
|
||||
const response = await authedFetch(`/update-guild/${serverID}`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(updatePayload),
|
||||
});
|
||||
|
||||
if (response.status === 200) {
|
||||
setGuild(guild);
|
||||
setPending(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Title title={`Editing ${guild.guild.name} - Roleypoly`} />
|
||||
<EditorTemplate {...appShellProps} guild={guild} onGuildChange={onGuildChange} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Editor;
|
Loading…
Add table
Add a link
Reference in a new issue