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:
41666 2021-07-05 12:18:40 -05:00 committed by GitHub
parent a37d481b18
commit 7d681d69d6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
48 changed files with 927 additions and 1100 deletions

View file

@ -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" />

View 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;