Removed extraneous hook for fetching guild metadata

This commit is contained in:
Alec LaLonde
2021-08-10 22:34:57 -06:00
committed by Alec LaLonde
parent 86bd86ba34
commit b1927b8a40
5 changed files with 217 additions and 211 deletions

View File

@@ -88,6 +88,7 @@ export const selectStyles: Styles = {
}),
};
export const MultiSelect: React.FC<SelectProps> = (props) => (
<Select styles={selectStyles} {...props} />
);
export const MultiSelect: React.FC<SelectProps> = React.forwardRef<
Select,
SelectProps
>((props, ref) => <Select styles={selectStyles} {...props} ref={ref} />);

View File

@@ -21,6 +21,7 @@ export const Field: React.FC<FieldProps> = ({ children, error, label }) => (
{error?.type === 'minLength' && 'Too short'}
{error?.type === 'maxLength' && 'Too long'}
{error?.type === 'min' && 'Too small'}
{error?.type === 'validate' && error.message}
</Text>
</Flex>

View File

@@ -1,12 +1,23 @@
import { Box, Input, MultiSelect, Select, Textarea, VStack } from '@metafam/ds';
import {
Box,
HStack,
Input,
LoadingState,
MetaButton,
MultiSelect,
Select,
Textarea,
VStack,
} from '@metafam/ds';
import { Field } from 'components/Forms/Field';
import {
DiscordRole,
GuildFragmentFragment,
GuildType_Enum,
useGetGuildMetadataQuery,
} from 'graphql/autogen/types';
import { useRouter } from 'next/router';
import React, { useMemo } from 'react';
import { useForm } from 'react-hook-form';
import { Controller, useForm } from 'react-hook-form';
const validations = {
guildname: {
@@ -21,11 +32,10 @@ const validations = {
type: {
required: true,
},
discord_admin_roles: {
required: true,
min: 1,
discordAdminRoles: {
validate: (roles: string[]) => roles != null && roles.length > 1,
},
discord_membership_roles: {
discordMembershipRoles: {
required: true,
min: 1,
},
@@ -35,11 +45,11 @@ export interface EditGuildFormInputs {
guildname: string;
name: string;
description: string | undefined | null;
discord_invite_url: string | undefined | null;
join_url: string | undefined | null;
logo_url: string | undefined | null;
website_url: string | undefined | null;
dao_address: string | undefined | null;
discordInviteUrl: string | undefined | null;
joinUrl: string | undefined | null;
logoUrl: string | undefined | null;
websiteUrl: string | undefined | null;
daoAddress: string | undefined | null;
type: GuildType_Enum;
discordAdminRoles: string[];
discordMembershipRoles: string[];
@@ -51,11 +61,11 @@ const getDefaultFormValues = (
guildname: guild.guildname,
name: guild.name,
description: guild.description || '',
discord_invite_url: guild.discord_invite_url || '',
join_url: guild.join_button_url || '',
logo_url: guild.logo || '',
website_url: guild.website_url || '',
dao_address: guild.moloch_address || '',
discordInviteUrl: guild.discord_invite_url || '',
joinUrl: guild.join_button_url || '',
logoUrl: guild.logo || '',
websiteUrl: guild.website_url || '',
daoAddress: guild.moloch_address || '',
type: guild.type,
discordAdminRoles: [],
discordMembershipRoles: [],
@@ -63,152 +73,206 @@ const getDefaultFormValues = (
type Props = {
workingGuild: GuildFragmentFragment;
allDiscordRoles: DiscordRole[];
onSubmit: (data: EditGuildFormInputs) => void;
children: React.ReactNode;
success?: boolean;
submitting?: boolean;
};
export const GuildForm: React.FC<Props> = ({
workingGuild,
allDiscordRoles,
onSubmit,
children,
success,
submitting,
}) => {
const router = useRouter();
const defaultValues = useMemo<EditGuildFormInputs>(
() => getDefaultFormValues(workingGuild),
[workingGuild],
);
const { register, errors, handleSubmit } = useForm<EditGuildFormInputs>({
const {
register,
errors,
handleSubmit,
control,
formState,
} = useForm<EditGuildFormInputs>({
defaultValues,
});
const roleOptions = useMemo(
() =>
allDiscordRoles.map((role) => ({
label: role.name,
value: role.id,
})),
[allDiscordRoles],
);
const [getGuildMetadataResponse] = useGetGuildMetadataQuery({
variables: { id: workingGuild.id },
});
const fetchingRoles =
getGuildMetadataResponse == null || getGuildMetadataResponse.fetching;
const roleOptions = useMemo(() => {
const allDiscordRoles =
getGuildMetadataResponse.data?.guild_metadata[0].discordRoles || [];
return allDiscordRoles.map((role) => ({
label: role.name,
value: role.id,
}));
}, [getGuildMetadataResponse]);
return (
<Box w="100%" maxW="30rem">
<VStack>
<form onSubmit={handleSubmit(onSubmit)}>
<Field label="Guildname" error={errors.guildname}>
<Input
type="text"
isRequired
name="guildname"
ref={register(validations.guildname)}
isInvalid={!!errors.guildname}
minLength={validations.guildname.minLength}
maxLength={validations.guildname.maxLength}
background="dark"
/>
<span>A unique identifier for your guild, like a username.</span>
</Field>
<Field label="Name" error={errors.name}>
<Input
type="text"
isRequired
name="name"
ref={register(validations.name)}
isInvalid={!!errors.name}
minLength={validations.guildname.minLength}
background="dark"
/>
<span>
Your guild&apos;s name. This is what will show throughout
MetaGame.
</span>
</Field>
<Field label="Description" error={errors.description}>
<Textarea
background="dark"
placeholder="What's your guild all about?"
name="description"
/>
</Field>
<Field label="Logo URL" error={errors.logo_url}>
<Input type="text" name="logo_url" background="dark" />
<span>
Logos should be square (same width and height) and reasonably
high-resolution.
</span>
</Field>
<Field label="Website URL" error={errors.website_url}>
<Input type="text" name="join_url" background="dark" />
<span>Your guild&apos;s main website.</span>
</Field>
<Field label="Discord Invite URL" error={errors.discord_invite_url}>
<Input
type="text"
name="discord_invite_url"
background="dark"
placeholder="https://discord.gg/fHvx7gu"
/>
<span>Your public invite URL for your Discord server.</span>
</Field>
<Field label="Join URL" error={errors.join_url}>
<Input type="text" name="join_url" background="dark" />
<span>The URL that the &quot;JOIN&quot; button will point to.</span>
</Field>
<Field label="DAO Address" error={errors.dao_address}>
<Input
type="text"
name="dao_address"
background="dark"
placeholder="0x..."
/>
<span>If your guild has a DAO, enter its address here.</span>
</Field>
<Field label="Type">
<Select
isRequired
name="type"
ref={register(validations.type)}
isInvalid={!!errors.type}
bg="dark"
color="white"
>
{Object.entries(GuildType_Enum).map(([key, value]) => (
<option key={value} value={value}>
{key}
</option>
))}
</Select>
</Field>
<Field label="Administrator Roles">
<MultiSelect
isRequired
name="discord_admin_roles"
isInvalid={!!errors.discordAdminRoles}
isMulti
options={roleOptions}
/>
<span>
Members of your server with these roles will have administration
privileges.
</span>
</Field>
<Field label="Membership Roles">
<MultiSelect
isRequired
name="discord_membership_roles"
isInvalid={!!errors.discordMembershipRoles}
isMulti
options={roleOptions}
/>
<span>
Members of your server with these roles will be considered members
of this guild.
</span>
</Field>
{children}
</form>
<Field label="Guildname" error={errors.guildname}>
<Input
type="text"
isRequired
name="guildname"
ref={register(validations.guildname)}
isInvalid={!!errors.guildname}
minLength={validations.guildname.minLength}
maxLength={validations.guildname.maxLength}
background="dark"
/>
<span>A unique identifier for your guild, like a username.</span>
</Field>
<Field label="Name" error={errors.name}>
<Input
type="text"
isRequired
name="name"
ref={register(validations.name)}
isInvalid={!!errors.name}
minLength={validations.guildname.minLength}
background="dark"
/>
<span>
Your guild&apos;s name. This is what will show throughout MetaGame.
</span>
</Field>
<Field label="Description" error={errors.description}>
<Textarea
background="dark"
placeholder="What's your guild all about?"
name="description"
ref={register}
/>
</Field>
<Field label="Logo URL" error={errors.logoUrl}>
<Input type="text" name="logoUrl" background="dark" ref={register} />
<span>
Logos should be square (same width and height) and reasonably
high-resolution.
</span>
</Field>
<Field label="Website URL" error={errors.websiteUrl}>
<Input type="text" name="joinUrl" background="dark" ref={register} />
<span>Your guild&apos;s main website.</span>
</Field>
<Field label="Discord Invite URL" error={errors.discordInviteUrl}>
<Input
type="text"
name="discordInviteUrl"
background="dark"
placeholder="https://discord.gg/fHvx7gu"
ref={register}
/>
<span>A public invite URL for your Discord server.</span>
</Field>
<Field label="Join URL" error={errors.joinUrl}>
<Input type="text" name="join_url" background="dark" ref={register} />
<span>The URL that the &quot;JOIN&quot; button will point to.</span>
</Field>
<Field label="DAO Address" error={errors.daoAddress}>
<Input
type="text"
name="daoAddress"
background="dark"
placeholder="0x..."
ref={register}
/>
<span>If your guild has a DAO, enter its address here.</span>
</Field>
<Field label="Type" error={errors.type}>
<Select
isRequired
name="type"
ref={register(validations.type)}
isInvalid={!!errors.type}
bg="dark"
color="white"
>
{Object.entries(GuildType_Enum).map(([key, value]) => (
<option key={value} value={value}>
{key}
</option>
))}
</Select>
</Field>
<Box my={10}>
{fetchingRoles ? (
<div>
Fetching roles from Discord...
<LoadingState />
</div>
) : (
<>
<Field
label="Administrator Roles"
error={
errors.discordAdminRoles != null
? {
type: 'validate',
message: 'Required',
}
: undefined
}
>
<Controller
name="discordAdminRoles"
control={control}
defaultValue={[]}
rules={validations.discordAdminRoles}
isRequired
isMulti
options={roleOptions}
as={MultiSelect}
/>
<span>
Members of your server with these roles will have
administration privileges.
</span>
</Field>
<Field label="Membership Roles">
<MultiSelect
isRequired
name="discordMembershipRoles"
isInvalid={!!errors.discordMembershipRoles}
isMulti
options={roleOptions}
ref={register(validations.discordMembershipRoles)}
/>
<span>
Members of your server with these roles will be considered
members of this guild.
</span>
</Field>
</>
)}
{JSON.stringify(formState.errors)}
</Box>
<HStack justify="space-between" mt={10} w="100%">
<MetaButton
isLoading={submitting}
loadingText="Submitting information..."
onClick={handleSubmit(onSubmit)}
isDisabled={success}
>
Submit guild information
</MetaButton>
<MetaButton
variant="outline"
onClick={() => router.push('/')}
isDisabled={submitting || success}
>
Cancel
</MetaButton>
</HStack>
</VStack>
</Box>
);

View File

@@ -1,21 +0,0 @@
import { DiscordRole, useGetGuildMetadataQuery } from 'graphql/autogen/types';
export type GetGuildMetadataHook = {
discordRoles: DiscordRole[];
fetching: boolean;
};
export const useGetGuildMetadata: (guildId: string) => GetGuildMetadataHook = (
guildId: string,
) => {
const [getGuildMetadataResponse] = useGetGuildMetadataQuery({
variables: { id: guildId },
});
const discordRoles =
getGuildMetadataResponse.data?.guild_metadata[0].discordRoles || [];
return {
discordRoles,
fetching: getGuildMetadataResponse.fetching,
};
};

View File

@@ -1,11 +1,4 @@
import {
ConfirmModal,
Flex,
HStack,
MetaButton,
MetaHeading,
useToast,
} from '@metafam/ds';
import { Flex, MetaHeading, useToast } from '@metafam/ds';
import { FlexContainer, PageContainer } from 'components/Container';
import { EditGuildFormInputs, GuildForm } from 'components/Guild/GuildForm';
import {
@@ -15,7 +8,6 @@ import {
useUpdateGuildMutation,
} from 'graphql/autogen/types';
import { getGuild } from 'graphql/getGuild';
import { useGetGuildMetadata } from 'lib/hooks/guilds';
import { useRouter } from 'next/router';
import React, { useEffect, useState } from 'react';
@@ -23,7 +15,6 @@ const SetupGuild: React.FC = () => {
const router = useRouter();
const [guild, setGuild] = useState<GuildFragmentFragment | undefined>();
const [exitAlert, setExitAlert] = useState<boolean>(false);
const [updateGuildState, updateGuild] = useUpdateGuildMutation();
const toast = useToast();
@@ -39,8 +30,6 @@ const SetupGuild: React.FC = () => {
fetchGuild();
}, [guildName]);
const { discordRoles } = useGetGuildMetadata(guild?.id);
if (guild == null) {
return <></>;
}
@@ -98,40 +87,12 @@ const SetupGuild: React.FC = () => {
>
<GuildForm
workingGuild={guild}
allDiscordRoles={discordRoles}
onSubmit={onSubmit}
>
<HStack justify="space-between" mt={10} w="100%">
<MetaButton
isLoading={updateGuildState.fetching}
loadingText="Submitting information..."
type="submit"
isDisabled={
!!updateGuildState.data?.saveGuildInformation?.success
}
>
Submit guild information
</MetaButton>
<MetaButton
variant="outline"
onClick={() => setExitAlert(true)}
isDisabled={
updateGuildState.fetching ||
!!updateGuildState.data?.saveGuildInformation?.success
}
>
Cancel
</MetaButton>
</HStack>
</GuildForm>
success={!!updateGuildState.data?.saveGuildInformation?.success}
submitting={updateGuildState.fetching}
/>
</Flex>
</FlexContainer>
<ConfirmModal
isOpen={exitAlert}
onNope={() => setExitAlert(false)}
onYep={() => setExitAlert(false)}
header="Are you sure you want to leave ?"
/>
</PageContainer>
);
};