mirror of
https://github.com/roleypoly/roleypoly.git
synced 2025-04-26 04:19:11 +00:00
remove pages, fix FUNDING.yml
This commit is contained in:
parent
90d63a6197
commit
03d07ea13c
14 changed files with 1 additions and 501 deletions
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
|
@ -1,7 +1,7 @@
|
||||||
# These are supported funding model platforms
|
# These are supported funding model platforms
|
||||||
|
|
||||||
github: kayteh
|
github: kayteh
|
||||||
patreon: kata
|
patreon: roleypoly
|
||||||
open_collective: # Replace with a single Open Collective username
|
open_collective: # Replace with a single Open Collective username
|
||||||
ko_fi: roleypoly
|
ko_fi: roleypoly
|
||||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
# Pages
|
|
||||||
|
|
||||||
This is the Next.js root for the main UI.
|
|
|
@ -1,15 +0,0 @@
|
||||||
import { InjectTypekitFont } from '@roleypoly/design-system/atoms/fonts';
|
|
||||||
import { AppProps } from 'next/app';
|
|
||||||
import * as React from 'react';
|
|
||||||
|
|
||||||
type Props = AppProps & {
|
|
||||||
sessionKey: string | null;
|
|
||||||
};
|
|
||||||
|
|
||||||
const App = (props: Props) => (
|
|
||||||
<>
|
|
||||||
<InjectTypekitFont />
|
|
||||||
<props.Component {...props.pageProps} />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
export default App;
|
|
|
@ -1,30 +0,0 @@
|
||||||
import Document, { DocumentContext } from 'next/document';
|
|
||||||
import { ServerStyleSheet } from 'styled-components';
|
|
||||||
|
|
||||||
export default class MyDocument extends Document {
|
|
||||||
static async getInitialProps(ctx: DocumentContext) {
|
|
||||||
const sheet = new ServerStyleSheet();
|
|
||||||
const originalRenderPage = ctx.renderPage;
|
|
||||||
|
|
||||||
try {
|
|
||||||
ctx.renderPage = () =>
|
|
||||||
originalRenderPage({
|
|
||||||
enhanceApp: (App) => (props) =>
|
|
||||||
sheet.collectStyles(<App {...props} />),
|
|
||||||
});
|
|
||||||
|
|
||||||
const initialProps = await Document.getInitialProps(ctx);
|
|
||||||
return {
|
|
||||||
...initialProps,
|
|
||||||
styles: (
|
|
||||||
<>
|
|
||||||
{initialProps.styles}
|
|
||||||
{sheet.getStyleElement()}
|
|
||||||
</>
|
|
||||||
),
|
|
||||||
};
|
|
||||||
} finally {
|
|
||||||
sheet.seal();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,70 +0,0 @@
|
||||||
import { AuthLogin } from '@roleypoly/design-system/templates/auth-login';
|
|
||||||
import { GetServerSideProps } from 'next';
|
|
||||||
import getConfig from 'next/config';
|
|
||||||
import Head from 'next/head';
|
|
||||||
import * as React from 'react';
|
|
||||||
import { GuildSlug } from 'roleypoly/common/types';
|
|
||||||
import { apiFetch } from 'roleypoly/common/utils/isomorphicFetch';
|
|
||||||
|
|
||||||
const loginPage = (props: { apiURI: string; guildSlug?: GuildSlug }) => {
|
|
||||||
React.useEffect(() => {
|
|
||||||
if (props.guildSlug) {
|
|
||||||
sessionStorage.setItem('redirectAfterNewSession', `/s/${props.guildSlug.id}`);
|
|
||||||
}
|
|
||||||
}, [props.guildSlug]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Head>
|
|
||||||
<title>
|
|
||||||
{props.guildSlug
|
|
||||||
? `Logging into ${props.guildSlug.name}... - Roleypoly`
|
|
||||||
: `Logging in... - Roleypoly`}
|
|
||||||
</title>
|
|
||||||
</Head>
|
|
||||||
<AuthLogin
|
|
||||||
onSendSecretCode={() => 0}
|
|
||||||
discordOAuthLink={`${props.apiURI}/login-bounce`}
|
|
||||||
guildSlug={props.guildSlug}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default loginPage;
|
|
||||||
|
|
||||||
export const getServerSideProps: GetServerSideProps = async (context) => {
|
|
||||||
const { publicRuntimeConfig } = getConfig();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const guildID = context.query['r'];
|
|
||||||
console.log({ guildID });
|
|
||||||
if (guildID) {
|
|
||||||
const guildSlug = await apiFetch<GuildSlug>(
|
|
||||||
`/get-slug/${guildID}`,
|
|
||||||
{},
|
|
||||||
context as any
|
|
||||||
);
|
|
||||||
|
|
||||||
if (guildSlug) {
|
|
||||||
return {
|
|
||||||
props: {
|
|
||||||
apiURI: publicRuntimeConfig.apiPublicURI,
|
|
||||||
guildSlug,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
// Do nothing.
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
props: {
|
|
||||||
apiURI: publicRuntimeConfig.apiPublicURI,
|
|
||||||
},
|
|
||||||
redirect: {
|
|
||||||
destination: `${publicRuntimeConfig.apiPublicURI}/login-bounce`,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -1,13 +0,0 @@
|
||||||
import { WhyNoRoles } from '@roleypoly/design-system/organisms/help-why-no-roles';
|
|
||||||
import {
|
|
||||||
HelpPageProps,
|
|
||||||
HelpPageTemplate,
|
|
||||||
} from '@roleypoly/design-system/templates/help-page';
|
|
||||||
|
|
||||||
const WhyNoRolesPage = (props: HelpPageProps) => (
|
|
||||||
<HelpPageTemplate {...props}>
|
|
||||||
<WhyNoRoles></WhyNoRoles>
|
|
||||||
</HelpPageTemplate>
|
|
||||||
);
|
|
||||||
|
|
||||||
export default WhyNoRolesPage;
|
|
|
@ -1,20 +0,0 @@
|
||||||
import { LandingTemplate } from '@roleypoly/design-system/templates/landing';
|
|
||||||
import { useRouter } from 'next/router';
|
|
||||||
import * as React from 'react';
|
|
||||||
import { useAppShellProps } from 'roleypoly/providers/appShellData';
|
|
||||||
|
|
||||||
const Index = () => {
|
|
||||||
const {
|
|
||||||
appShellProps: { guilds, user },
|
|
||||||
} = useAppShellProps();
|
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
if (user || guilds) {
|
|
||||||
void router.replace('/servers');
|
|
||||||
}
|
|
||||||
}, [guilds, user]);
|
|
||||||
|
|
||||||
return <LandingTemplate user={user} guilds={guilds} />;
|
|
||||||
};
|
|
||||||
export default Index;
|
|
|
@ -1,17 +0,0 @@
|
||||||
import { Error } from '@roleypoly/design-system/templates/errors';
|
|
||||||
import { NextPageContext } from 'next';
|
|
||||||
import * as React from 'react';
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
errorCode: string | number | any;
|
|
||||||
};
|
|
||||||
|
|
||||||
const ErrorPage = (props: Props) => <Error code={props.errorCode} />;
|
|
||||||
|
|
||||||
ErrorPage.getInitialProps = (context: NextPageContext): Props => {
|
|
||||||
return {
|
|
||||||
errorCode: context.err || context.query.error_code,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ErrorPage;
|
|
|
@ -1,56 +0,0 @@
|
||||||
import { Hero } from '@roleypoly/design-system/atoms/hero';
|
|
||||||
import { AccentTitle } from '@roleypoly/design-system/atoms/typography';
|
|
||||||
import { AppShell } from '@roleypoly/design-system/organisms/app-shell';
|
|
||||||
import fetch from 'isomorphic-unfetch';
|
|
||||||
import { GetServerSideProps } from 'next';
|
|
||||||
import getConfig from 'next/config';
|
|
||||||
import nookies from 'nookies';
|
|
||||||
import * as React from 'react';
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
sessionID: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const Logout = (props: Props) => {
|
|
||||||
React.useEffect(() => {
|
|
||||||
sessionStorage.removeItem('session_key');
|
|
||||||
sessionStorage.removeItem('session_data');
|
|
||||||
location.href = '/';
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<AppShell>
|
|
||||||
<Hero>
|
|
||||||
<AccentTitle>Logging you out...</AccentTitle>
|
|
||||||
</Hero>
|
|
||||||
</AppShell>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getServerSideProps: GetServerSideProps = async (context) => {
|
|
||||||
const { publicRuntimeConfig } = getConfig();
|
|
||||||
|
|
||||||
const sessionKey = nookies.get(context)['rp_session_key'];
|
|
||||||
if (!sessionKey) {
|
|
||||||
return { props: {} };
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
await fetch(`${publicRuntimeConfig.apiPublicURI}/revoke-session`, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
authorization: `Bearer ${sessionKey}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} catch (e) {}
|
|
||||||
|
|
||||||
nookies.set(context, 'rp_session_key', '', {
|
|
||||||
httpOnly: true,
|
|
||||||
maxAge: 0,
|
|
||||||
path: '/',
|
|
||||||
sameSite: 'strict',
|
|
||||||
});
|
|
||||||
|
|
||||||
return { props: {} };
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Logout;
|
|
|
@ -1,57 +0,0 @@
|
||||||
import { Hero } from '@roleypoly/design-system/atoms/hero';
|
|
||||||
import { AccentTitle } from '@roleypoly/design-system/atoms/typography';
|
|
||||||
import { AppShell } from '@roleypoly/design-system/organisms/app-shell';
|
|
||||||
import { NextPageContext } from 'next';
|
|
||||||
import getConfig from 'next/config';
|
|
||||||
import { useRouter } from 'next/router';
|
|
||||||
import nookies from 'nookies';
|
|
||||||
import * as React from 'react';
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
sessionID: string;
|
|
||||||
apiURI: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const NewSession = (props: Props) => {
|
|
||||||
const { sessionID, apiURI } = props;
|
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
sessionStorage.setItem('session_key', sessionID);
|
|
||||||
localStorage.setItem('api_uri', apiURI);
|
|
||||||
|
|
||||||
const nextURL = sessionStorage.getItem('redirectAfterNewSession') || '/servers';
|
|
||||||
sessionStorage.removeItem('redirectAfterNewSession');
|
|
||||||
void router.replace(nextURL);
|
|
||||||
}, [sessionID, apiURI]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<AppShell>
|
|
||||||
<Hero>
|
|
||||||
<AccentTitle>Logging you in...</AccentTitle>
|
|
||||||
</Hero>
|
|
||||||
</AppShell>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getServerSideProps = async (
|
|
||||||
context: NextPageContext
|
|
||||||
): Promise<{ props: Props }> => {
|
|
||||||
const { publicRuntimeConfig } = getConfig();
|
|
||||||
const apiURI = publicRuntimeConfig.apiPublicURI;
|
|
||||||
const sessionID = context.query.session_id as string;
|
|
||||||
if (!sessionID) {
|
|
||||||
throw new Error("I shouldn't be here today.");
|
|
||||||
}
|
|
||||||
|
|
||||||
nookies.set(context, 'rp_session_key', sessionID, {
|
|
||||||
httpOnly: true,
|
|
||||||
maxAge: 60 * 60 * 6,
|
|
||||||
path: '/',
|
|
||||||
sameSite: 'strict',
|
|
||||||
});
|
|
||||||
|
|
||||||
return { props: { sessionID, apiURI } };
|
|
||||||
};
|
|
||||||
|
|
||||||
export default NewSession;
|
|
|
@ -1,159 +0,0 @@
|
||||||
import { RolePickerTemplate } from '@roleypoly/design-system/templates/role-picker';
|
|
||||||
import { NextPage, NextPageContext } from 'next';
|
|
||||||
import Head from 'next/head';
|
|
||||||
import { useRouter } from 'next/router';
|
|
||||||
import * as React from 'react';
|
|
||||||
import {
|
|
||||||
Member,
|
|
||||||
PresentableGuild,
|
|
||||||
Role,
|
|
||||||
RoleTransaction,
|
|
||||||
RoleUpdate,
|
|
||||||
TransactionType,
|
|
||||||
UserGuildPermissions,
|
|
||||||
} from 'roleypoly/common/types';
|
|
||||||
import { apiFetch, getSessionKey } from 'roleypoly/common/utils/isomorphicFetch';
|
|
||||||
import { useAppShellProps } from 'roleypoly/providers/appShellData';
|
|
||||||
|
|
||||||
type Props =
|
|
||||||
| {
|
|
||||||
data: PresentableGuild;
|
|
||||||
redirect: null;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
data: null;
|
|
||||||
redirect: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const createUpdatePayload = (
|
|
||||||
oldRoles: Role['id'][],
|
|
||||||
newRoles: Role['id'][]
|
|
||||||
): RoleTransaction[] => {
|
|
||||||
const transactions: RoleTransaction[] = [];
|
|
||||||
|
|
||||||
// Removes: old roles not in new roles
|
|
||||||
for (let oldID of oldRoles) {
|
|
||||||
if (!newRoles.includes(oldID)) {
|
|
||||||
transactions.push({
|
|
||||||
id: oldID,
|
|
||||||
action: TransactionType.Remove,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adds: new roles not in old roles
|
|
||||||
for (let newID of newRoles) {
|
|
||||||
if (!oldRoles.includes(newID)) {
|
|
||||||
transactions.push({
|
|
||||||
id: newID,
|
|
||||||
action: TransactionType.Add,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return transactions;
|
|
||||||
};
|
|
||||||
|
|
||||||
const RolePickerPage: NextPage<Props> = (props) => {
|
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
if (props.redirect !== null) {
|
|
||||||
void router.replace(props.redirect || '/auth/login');
|
|
||||||
}
|
|
||||||
}, [props.redirect]);
|
|
||||||
|
|
||||||
if (!props.data) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { appShellProps } = useAppShellProps();
|
|
||||||
|
|
||||||
const [isPending, updatePending] = React.useState(false);
|
|
||||||
const [memberRoles, updateMemberRoles] = React.useState(props.data.member.roles);
|
|
||||||
|
|
||||||
const handlePickerSubmit = (guildID: string, oldRoles: Role['id'][]) => async (
|
|
||||||
newRoles: Role['id'][]
|
|
||||||
) => {
|
|
||||||
if (isPending) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
updatePending(true);
|
|
||||||
|
|
||||||
const payload: RoleUpdate = {
|
|
||||||
knownState: oldRoles,
|
|
||||||
transactions: createUpdatePayload(oldRoles, newRoles),
|
|
||||||
};
|
|
||||||
|
|
||||||
const patchedMember = await apiFetch<Member>(`/update-roles/${guildID}`, {
|
|
||||||
method: 'PATCH',
|
|
||||||
body: JSON.stringify(payload),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!patchedMember) {
|
|
||||||
console.error('role update failed', patchedMember);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
updatePending(false);
|
|
||||||
updateMemberRoles(patchedMember.roles);
|
|
||||||
console.log('accepted', { patchedMember });
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Head>
|
|
||||||
<title>Picking roles on {props.data.guild.name} - Roleypoly</title>
|
|
||||||
</Head>
|
|
||||||
<RolePickerTemplate
|
|
||||||
user={appShellProps.user}
|
|
||||||
guilds={appShellProps.guilds}
|
|
||||||
guild={props.data.guild}
|
|
||||||
roles={props.data.roles}
|
|
||||||
guildData={props.data.data}
|
|
||||||
member={{ ...props.data.member, roles: memberRoles }}
|
|
||||||
editable={props.data.guild.permissionLevel !== UserGuildPermissions.User}
|
|
||||||
activeGuildId={props.data.id}
|
|
||||||
onSubmit={handlePickerSubmit(props.data.id, memberRoles)}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
RolePickerPage.getInitialProps = async (context: NextPageContext): Promise<Props> => {
|
|
||||||
const serverID = context.query.id;
|
|
||||||
if (!serverID) {
|
|
||||||
throw new Error('serverID missing');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!getSessionKey()) {
|
|
||||||
return {
|
|
||||||
data: null,
|
|
||||||
redirect: `/auth/login?r=${serverID}`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const pickerData = await apiFetch<PresentableGuild>(
|
|
||||||
`/get-picker-data/${serverID}`,
|
|
||||||
undefined,
|
|
||||||
context
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!pickerData) {
|
|
||||||
throw new Error('Picker data failed.');
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
data: pickerData,
|
|
||||||
redirect: null,
|
|
||||||
};
|
|
||||||
} catch (e) {
|
|
||||||
return {
|
|
||||||
data: null,
|
|
||||||
redirect: `/auth/login?r=${serverID}`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export default RolePickerPage;
|
|
|
@ -1,10 +0,0 @@
|
||||||
import Link from 'next/link';
|
|
||||||
import * as React from 'react';
|
|
||||||
|
|
||||||
const ServerEditor = () => (
|
|
||||||
<div>
|
|
||||||
<Link href="/">Go back</Link>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
export default ServerEditor;
|
|
|
@ -1,33 +0,0 @@
|
||||||
import { ServerSetupTemplate } from '@roleypoly/design-system/templates/server-setup';
|
|
||||||
import { NextPageContext } from 'next';
|
|
||||||
import { useRouter } from 'next/router';
|
|
||||||
import * as React from 'react';
|
|
||||||
import { useAppShellProps } from 'roleypoly/providers/appShellData';
|
|
||||||
|
|
||||||
const serverSetup = (props: { guildID: string }) => {
|
|
||||||
const { appShellProps } = useAppShellProps();
|
|
||||||
|
|
||||||
const guildSlug = appShellProps.guilds?.find((guild) => guild.id === props.guildID);
|
|
||||||
|
|
||||||
if (!guildSlug) {
|
|
||||||
const router = useRouter();
|
|
||||||
void router.push('/machinery/error?error_code=404');
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ServerSetupTemplate
|
|
||||||
{...appShellProps}
|
|
||||||
activeGuildId={props.guildID}
|
|
||||||
guildSlug={guildSlug}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
serverSetup.getInitialProps = async (context: NextPageContext) => {
|
|
||||||
return {
|
|
||||||
guildID: context.query.id,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default serverSetup;
|
|
|
@ -1,17 +0,0 @@
|
||||||
import { ServersTemplate } from '@roleypoly/design-system/templates/servers';
|
|
||||||
import Head from 'next/head';
|
|
||||||
import { useAppShellProps } from 'roleypoly/providers/appShellData';
|
|
||||||
|
|
||||||
const Servers = () => {
|
|
||||||
const { appShellProps } = useAppShellProps();
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Head>
|
|
||||||
<title>Viewing your servers - Roleypoly</title>
|
|
||||||
</Head>
|
|
||||||
<ServersTemplate {...appShellProps} guilds={appShellProps.guilds || []} />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Servers;
|
|
Loading…
Add table
Reference in a new issue