ui(admin): add views for settings

This commit is contained in:
Matthew Penner 2021-10-30 13:12:02 -06:00
parent 70cf5c17aa
commit 469c0b40a3
No known key found for this signature in database
GPG key ID: BAB67850901908A8
8 changed files with 249 additions and 47 deletions

View file

@ -251,7 +251,7 @@ export default function EggSettingsContainer ({ egg }: { egg: Egg }) {
<EggProcessContainer ref={ref} css={tw`mb-6`}/> <EggProcessContainer ref={ref} css={tw`mb-6`}/>
<div css={tw`bg-neutral-700 rounded shadow-md py-2 px-6 mb-16`}> <div css={tw`bg-neutral-700 rounded shadow-md px-4 xl:px-5 py-4 mb-16`}>
<div css={tw`flex flex-row`}> <div css={tw`flex flex-row`}>
<EggDeleteButton <EggDeleteButton
eggId={egg.id} eggId={egg.id}

View file

@ -66,51 +66,49 @@ function CreateAllocationForm ({ nodeId }: { nodeId: number }) {
ports: array(number()).min(1, 'You must select at least one port.'), ports: array(number()).min(1, 'You must select at least one port.'),
})} })}
> >
{ {({ isSubmitting, isValid }) => (
({ isSubmitting, isValid }) => ( <Form>
<Form> <SelectField
<SelectField id={'ips'}
id={'ips'} name={'ips'}
name={'ips'} label={'IPs and CIDRs'}
label={'IPs and CIDRs'} options={ips}
options={ips} isValidNewOption={isValidIP}
isValidNewOption={isValidIP} isMulti
isMulti isSearchable
isSearchable isCreatable
isCreatable css={tw`mb-6`}
css={tw`mb-6`} />
<SelectField
id={'ports'}
name={'ports'}
label={'Ports'}
options={ports}
isValidNewOption={isValidPort}
isMulti
isSearchable
isCreatable
/>
<div css={tw`mt-6`}>
<Field
id={'alias'}
name={'alias'}
label={'Alias'}
type={'text'}
/> />
</div>
<SelectField <div css={tw`w-full flex flex-row items-center mt-6`}>
id={'ports'} <div css={tw`flex ml-auto`}>
name={'ports'} <Button type={'submit'} disabled={isSubmitting || !isValid}>
label={'Ports'} Create Allocations
options={ports} </Button>
isValidNewOption={isValidPort}
isMulti
isSearchable
isCreatable
/>
<div css={tw`mt-6`}>
<Field
id={'alias'}
name={'alias'}
label={'Alias'}
type={'text'}
/>
</div> </div>
</div>
<div css={tw`w-full flex flex-row items-center mt-6`}> </Form>
<div css={tw`flex ml-auto`}> )}
<Button type={'submit'} disabled={isSubmitting || !isValid}>
Create Allocations
</Button>
</div>
</div>
</Form>
)
}
</Formik> </Formik>
); );
} }

View file

@ -79,7 +79,7 @@ export default () => {
</div> </div>
<div css={tw`flex flex-col`}> <div css={tw`flex flex-col`}>
<ServerResourceBox/> <ServerResourceBox/>
<div css={tw`bg-neutral-700 rounded shadow-md px-4 xl:px-5 py-5 mt-6`}> <div css={tw`bg-neutral-700 rounded shadow-md px-4 xl:px-5 py-4 mt-6`}>
<div css={tw`flex flex-row`}> <div css={tw`flex flex-row`}>
<ServerDeleteButton/> <ServerDeleteButton/>
<Button <Button

View file

@ -0,0 +1,46 @@
import Field, { FieldRow } from '@/components/elements/Field';
import { Form, Formik } from 'formik';
import React from 'react';
import AdminBox from '@/components/admin/AdminBox';
import tw from 'twin.macro';
export default () => {
const submit = () => {
//
};
return (
<Formik
onSubmit={submit}
initialValues={{}}
>
<Form>
<div css={tw`grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-6`}>
<AdminBox title="Branding">
<FieldRow>
<Field
id={'appName'}
name={'appName'}
type={'text'}
label={'App Name'}
description={''}
/>
</FieldRow>
</AdminBox>
<AdminBox title="Analytics">
<FieldRow>
<Field
id={'googleAnalytics'}
name={'googleAnalytics'}
type={'text'}
label={'Google Analytics'}
description={''}
/>
</FieldRow>
</AdminBox>
</div>
</Form>
</Formik>
);
};

View file

@ -0,0 +1,111 @@
import Button from '@/components/elements/Button';
import Label from '@/components/elements/Label';
import { Form, Formik } from 'formik';
import React from 'react';
import tw from 'twin.macro';
import AdminBox from '@/components/admin/AdminBox';
import Field, { FieldRow } from '@/components/elements/Field';
import Select from '@/components/elements/Select';
export default () => {
const submit = () => {
//
};
return (
<Formik
onSubmit={submit}
initialValues={{
smtpHost: 'smtp.example.com',
smtpPort: 587,
smtpEncryption: 'tls',
username: '',
password: '',
mailFrom: 'no-reply@example.com',
mailFromName: 'Pterodactyl Panel',
}}
>
{({ isSubmitting, isValid }) => (
<Form>
<AdminBox title="Mail">
<FieldRow css={tw`lg:grid-cols-3`}>
<Field
id={'smtpHost'}
name={'smtpHost'}
type={'text'}
label={'SMTP Host'}
description={''}
/>
<Field
id={'smtpPort'}
name={'smtpPort'}
type={'number'}
label={'SMTP Port'}
description={''}
/>
<div>
<Label>Encryption</Label>
<Select
id={'smtpEncryption'}
name={'smtpEncryption'}
defaultValue={'tls'}
>
<option value="">None</option>
<option value="ssl">Secure Sockets Layer (SSL)</option>
<option value="tls">Transport Layer Security (TLS)</option>
</Select>
</div>
</FieldRow>
<FieldRow>
<Field
id={'username'}
name={'username'}
type={'text'}
label={'Username'}
description={''}
/>
<Field
id={'password'}
name={'password'}
type={'password'}
label={'Password'}
description={''}
/>
</FieldRow>
<FieldRow>
<Field
id={'mailFrom'}
name={'mailFrom'}
type={'text'}
label={'Mail From'}
description={''}
/>
<Field
id={'mailFromName'}
name={'mailFromName'}
type={'text'}
label={'Mail From Name'}
description={''}
/>
</FieldRow>
</AdminBox>
<div css={tw`bg-neutral-700 rounded shadow-md px-4 xl:px-5 py-4 mt-6`}>
<div css={tw`flex flex-row`}>
<Button
type="submit"
size="small"
css={tw`ml-auto`}
disabled={isSubmitting || !isValid}
>
Save Changes
</Button>
</div>
</div>
</Form>
)}
</Formik>
);
};

View file

@ -1,8 +1,17 @@
import MailSettings from '@/components/admin/settings/MailSettings';
import { AdjustmentsIcon, ChipIcon, CodeIcon, MailIcon, ShieldCheckIcon } from '@heroicons/react/outline';
import React from 'react'; import React from 'react';
import { Route, useLocation } from 'react-router';
import { Switch } from 'react-router-dom';
import tw from 'twin.macro'; import tw from 'twin.macro';
import FlashMessageRender from '@/components/FlashMessageRender';
import AdminContentBlock from '@/components/admin/AdminContentBlock'; import AdminContentBlock from '@/components/admin/AdminContentBlock';
import { SubNavigation, SubNavigationLink } from '@/components/admin/SubNavigation';
import GeneralSettings from '@/components/admin/settings/GeneralSettings';
export default () => { export default () => {
const location = useLocation();
return ( return (
<AdminContentBlock title={'Settings'}> <AdminContentBlock title={'Settings'}>
<div css={tw`w-full flex flex-row items-center mb-8`}> <div css={tw`w-full flex flex-row items-center mb-8`}>
@ -11,6 +20,44 @@ export default () => {
<p css={tw`text-base text-neutral-400 whitespace-nowrap overflow-ellipsis overflow-hidden`}>Configure and manage settings for Pterodactyl.</p> <p css={tw`text-base text-neutral-400 whitespace-nowrap overflow-ellipsis overflow-hidden`}>Configure and manage settings for Pterodactyl.</p>
</div> </div>
</div> </div>
<FlashMessageRender byKey={'settings'} css={tw`mb-4`}/>
<SubNavigation>
<SubNavigationLink to="/admin/settings" name="General">
<ChipIcon/>
</SubNavigationLink>
<SubNavigationLink to="/admin/settings/mail" name="Mail">
<MailIcon/>
</SubNavigationLink>
<SubNavigationLink to="/admin/settings/security" name="Security">
<ShieldCheckIcon/>
</SubNavigationLink>
<SubNavigationLink to="/admin/settings/features" name="Features">
<AdjustmentsIcon/>
</SubNavigationLink>
<SubNavigationLink to="/admin/settings/advanced" name="Advanced">
<CodeIcon/>
</SubNavigationLink>
</SubNavigation>
<Switch location={location}>
<Route path="/admin/settings" exact>
<GeneralSettings/>
</Route>
<Route path="/admin/settings/mail" exact>
<MailSettings/>
</Route>
<Route path="/admin/settings/security" exact>
<p>Security</p>
</Route>
<Route path="/admin/settings/features" exact>
<p>Features</p>
</Route>
<Route path="/admin/settings/advanced" exact>
<p>Advanced</p>
</Route>
</Switch>
</AdminContentBlock> </AdminContentBlock>
); );
}; };

View file

@ -77,9 +77,9 @@ export const TextareaField = forwardRef<HTMLTextAreaElement, TextareaProps>(
TextareaField.displayName = 'TextareaField'; TextareaField.displayName = 'TextareaField';
export const FieldRow = styled.div` export const FieldRow = styled.div`
${tw`grid grid-cols-1 sm:grid-cols-2 gap-x-6 mb-6`}; ${tw`grid grid-cols-1 sm:grid-cols-2 gap-x-6 gap-y-6 mb-6`};
& > div { & > div {
${tw`mb-6 sm:mb-0 sm:w-full sm:flex sm:flex-col`}; ${tw`sm:w-full sm:flex sm:flex-col`};
} }
`; `;

View file

@ -120,7 +120,7 @@ const AdminRouter = ({ location, match }: RouteComponentProps) => {
<div css={tw`w-full flex flex-col mx-auto`} style={{ maxWidth: '86rem' }}> <div css={tw`w-full flex flex-col mx-auto`} style={{ maxWidth: '86rem' }}>
<Switch location={location}> <Switch location={location}>
<Route path={`${match.path}`} component={OverviewContainer} exact/> <Route path={`${match.path}`} component={OverviewContainer} exact/>
<Route path={`${match.path}/settings`} component={SettingsContainer} exact/> <Route path={`${match.path}/settings`} component={SettingsContainer}/>
<Route path={`${match.path}/databases`} component={DatabasesContainer} exact/> <Route path={`${match.path}/databases`} component={DatabasesContainer} exact/>
<Route path={`${match.path}/databases/new`} component={NewDatabaseContainer} exact/> <Route path={`${match.path}/databases/new`} component={NewDatabaseContainer} exact/>
<Route path={`${match.path}/databases/:id`} component={DatabaseEditContainer} exact/> <Route path={`${match.path}/databases/:id`} component={DatabaseEditContainer} exact/>