Get settings page in working order

This commit is contained in:
Dane Everitt 2020-07-04 15:58:14 -07:00
parent 1e163aa792
commit d27bda1c74
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
5 changed files with 80 additions and 60 deletions

View file

@ -10,20 +10,10 @@ interface Props {
isSecondary?: boolean;
}
const StyledButton = styled.button<Omit<Props, 'isLoading'>>`
${tw`relative inline-block rounded p-2 uppercase tracking-wide text-sm transition-all duration-150`};
const ButtonStyle = styled.button<Omit<Props, 'isLoading'>>`
${tw`relative inline-block rounded p-2 uppercase tracking-wide text-sm transition-all duration-150 border`};
${props => props.isSecondary && css<Props>`
${tw`border border-neutral-600 bg-transparent text-neutral-200`};
&:hover:not(:disabled) {
${tw`border-neutral-500 text-neutral-100`};
${props => props.color === 'red' && tw`bg-red-500 border-red-600 text-red-50`};
${props => props.color === 'green' && tw`bg-green-500 border-green-600 text-green-50`};
}
`};
${props => (!props.color || props.color === 'primary') && css<Props>`
${props => ((!props.isSecondary && !props.color) || props.color === 'primary') && css<Props>`
${props => !props.isSecondary && tw`bg-primary-500 border-primary-600 border text-primary-50`};
&:hover:not(:disabled) {
@ -32,7 +22,7 @@ const StyledButton = styled.button<Omit<Props, 'isLoading'>>`
`};
${props => props.color === 'grey' && css`
${tw`border border-neutral-600 bg-neutral-500 text-neutral-50`};
${tw`border-neutral-600 bg-neutral-500 text-neutral-50`};
&:hover:not(:disabled) {
${tw`bg-neutral-600 border-neutral-700`};
@ -40,7 +30,7 @@ const StyledButton = styled.button<Omit<Props, 'isLoading'>>`
`};
${props => props.color === 'green' && css<Props>`
${tw`border border-green-600 bg-green-500 text-green-50`};
${tw`border-green-600 bg-green-500 text-green-50`};
&:hover:not(:disabled) {
${tw`bg-green-600 border-green-700`};
@ -54,7 +44,7 @@ const StyledButton = styled.button<Omit<Props, 'isLoading'>>`
`};
${props => props.color === 'red' && css<Props>`
${tw`border border-red-600 bg-red-500 text-red-50`};
${tw`border-red-600 bg-red-500 text-red-50`};
&:hover:not(:disabled) {
${tw`bg-red-600 border-red-700`};
@ -72,13 +62,23 @@ const StyledButton = styled.button<Omit<Props, 'isLoading'>>`
${props => props.size === 'large' && tw`p-4 text-sm`};
${props => props.size === 'xlarge' && tw`p-4 w-full`};
${props => props.isSecondary && css<Props>`
${tw`border-neutral-600 bg-transparent text-neutral-200`};
&:hover:not(:disabled) {
${tw`border-neutral-500 text-neutral-100`};
${props => props.color === 'red' && tw`bg-red-500 border-red-600 text-red-50`};
${props => props.color === 'green' && tw`bg-green-500 border-green-600 text-green-50`};
}
`};
&:disabled { opacity: 0.55; cursor: default }
`;
type ComponentProps = Omit<JSX.IntrinsicElements['button'], 'ref' | keyof Props> & Props;
const Button: React.FC<ComponentProps> = ({ children, isLoading, ...props }) => (
<StyledButton {...props}>
<ButtonStyle {...props}>
{isLoading &&
<div css={tw`flex absolute justify-center items-center w-full h-full left-0 top-0`}>
<Spinner size={'small'}/>
@ -87,7 +87,12 @@ const Button: React.FC<ComponentProps> = ({ children, isLoading, ...props }) =>
<span css={isLoading ? tw`text-transparent` : undefined}>
{children}
</span>
</StyledButton>
</ButtonStyle>
);
type LinkProps = Omit<JSX.IntrinsicElements['a'], 'ref' | keyof Props> & Props;
const LinkButton: React.FC<LinkProps> = props => <ButtonStyle as={'a'} {...props}/>;
export { LinkButton, ButtonStyle };
export default Button;

View file

@ -5,6 +5,7 @@ import getWebsocketToken from '@/api/server/getWebsocketToken';
import ContentContainer from '@/components/elements/ContentContainer';
import { CSSTransition } from 'react-transition-group';
import Spinner from '@/components/elements/Spinner';
import tw from 'twin.macro';
export default () => {
const server = ServerContext.useStoreState(state => state.server.data);
@ -67,10 +68,10 @@ export default () => {
return (
error ?
<CSSTransition timeout={250} in={true} appear={true} classNames={'fade'}>
<div className={'bg-red-500 py-2'}>
<ContentContainer className={'flex items-center justify-center'}>
<div css={tw`bg-red-500 py-2`}>
<ContentContainer css={tw`flex items-center justify-center`}>
<Spinner size={'small'}/>
<p className={'ml-2 text-sm text-red-100'}>
<p css={tw`ml-2 text-sm text-red-100`}>
We&apos;re having some trouble connecting to your server, please wait...
</p>
</ContentContainer>

View file

@ -1,12 +1,13 @@
import React, { useState } from 'react';
import { ServerContext } from '@/state/server';
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
import TitledGreyBox from '@/components/elements/TitledGreyBox';
import ConfirmationModal from '@/components/elements/ConfirmationModal';
import reinstallServer from '@/api/server/reinstallServer';
import { Actions, useStoreActions } from 'easy-peasy';
import { ApplicationStore } from '@/state';
import { httpErrorToHuman } from '@/api/http';
import tw from 'twin.macro';
import Button from '@/components/elements/Button';
export default () => {
const uuid = ServerContext.useStoreState(state => state.server.data!.uuid);
@ -19,7 +20,11 @@ export default () => {
setIsSubmitting(true);
reinstallServer(uuid)
.then(() => {
addFlash({ key: 'settings', type: 'success', message: 'Your server has begun the reinstallation process.' });
addFlash({
key: 'settings',
type: 'success',
message: 'Your server has begun the reinstallation process.',
});
})
.catch(error => {
console.error(error);
@ -30,10 +35,10 @@ export default () => {
setIsSubmitting(false);
setModalVisible(false);
});
}
};
return (
<TitledGreyBox title={'Reinstall Server'} className={'relative'}>
<TitledGreyBox title={'Reinstall Server'} css={tw`relative`}>
<ConfirmationModal
title={'Confirm server reinstallation'}
buttonText={'Yes, reinstall server'}
@ -42,21 +47,26 @@ export default () => {
visible={modalVisible}
onDismissed={() => setModalVisible(false)}
>
Your server will be stopped and some files may be deleted or modified during this process, are you sure you wish to continue?
Your server will be stopped and some files may be deleted or modified during this process, are you sure
you wish to continue?
</ConfirmationModal>
<p className={'text-sm'}>
<p css={tw`text-sm`}>
Reinstalling your server will stop it, and then re-run the installation script that initially
set it up. <strong className={'font-bold'}>Some files may be deleted or modified during this process,
please back up your data before continuing.</strong>
set it up.&nbsp;
<strong css={tw`font-medium`}>
Some files may be deleted or modified during this process, please back up your data before
continuing.
</strong>
</p>
<div className={'mt-6 text-right'}>
<button
<div css={tw`mt-6 text-right`}>
<Button
type={'button'}
className={'btn btn-sm btn-secondary btn-red'}
color={'red'}
isSecondary
onClick={() => setModalVisible(true)}
>
Reinstall Server
</button>
</Button>
</div>
</TitledGreyBox>
);

View file

@ -9,6 +9,8 @@ import { object, string } from 'yup';
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
import { ApplicationStore } from '@/state';
import { httpErrorToHuman } from '@/api/http';
import Button from '@/components/elements/Button';
import tw from 'twin.macro';
interface Values {
name: string;
@ -18,19 +20,19 @@ const RenameServerBox = () => {
const { isSubmitting } = useFormikContext<Values>();
return (
<TitledGreyBox title={'Change Server Name'} className={'relative'}>
<TitledGreyBox title={'Change Server Name'} css={tw`relative`}>
<SpinnerOverlay visible={isSubmitting}/>
<Form className={'mb-0'}>
<Form css={tw`mb-0`}>
<Field
id={'name'}
name={'name'}
label={'Server Name'}
type={'text'}
/>
<div className={'mt-6 text-right'}>
<button type={'submit'} className={'btn btn-sm btn-primary'}>
<div css={tw`mt-6 text-right`}>
<Button type={'submit'}>
Save
</button>
</Button>
</div>
</Form>
</TitledGreyBox>

View file

@ -9,6 +9,10 @@ import FlashMessageRender from '@/components/FlashMessageRender';
import Can from '@/components/elements/Can';
import ReinstallServerBox from '@/components/server/settings/ReinstallServerBox';
import PageContentBlock from '@/components/elements/PageContentBlock';
import tw from 'twin.macro';
import Input from '@/components/elements/Input';
import Label from '@/components/elements/Label';
import Button, { LinkButton } from '@/components/elements/Button';
export default () => {
const user = useStoreState<ApplicationStore, UserData>(state => state.user.data!);
@ -16,52 +20,50 @@ export default () => {
return (
<PageContentBlock>
<FlashMessageRender byKey={'settings'} className={'mb-4'}/>
<div className={'md:flex'}>
<FlashMessageRender byKey={'settings'} css={tw`mb-4`}/>
<div css={tw`md:flex`}>
<Can action={'file.sftp'}>
<div className={'w-full md:flex-1 md:max-w-1/2 md:mr-10'}>
<div css={tw`w-full md:flex-1 md:mr-10`}>
<TitledGreyBox title={'SFTP Details'}>
<div>
<label className={'input-dark-label'}>Server Address</label>
<input
<Label>Server Address</Label>
<Input
type={'text'}
className={'input-dark'}
value={`sftp://${server.sftpDetails.ip}:${server.sftpDetails.port}`}
readOnly={true}
readOnly
/>
</div>
<div className={'mt-6'}>
<label className={'input-dark-label'}>Username</label>
<input
<div css={tw`mt-6`}>
<Label>Username</Label>
<Input
type={'text'}
className={'input-dark'}
value={`${user.username}.${server.id}`}
readOnly={true}
readOnly
/>
</div>
<div className={'mt-6 flex items-center'}>
<div className={'flex-1'}>
<div className={'border-l-4 border-cyan-500 p-3'}>
<p className={'text-xs text-neutral-200'}>
<div css={tw`mt-6 flex items-center`}>
<div css={tw`flex-1`}>
<div css={tw`border-l-4 border-cyan-500 p-3`}>
<p css={tw`text-xs text-neutral-200`}>
Your SFTP password is the same as the password you use to access this panel.
</p>
</div>
</div>
<div className={'ml-4'}>
<a
<div css={tw`ml-4`}>
<LinkButton
isSecondary
href={`sftp://${user.username}.${server.id}@${server.sftpDetails.ip}:${server.sftpDetails.port}`}
className={'btn btn-sm btn-secondary'}
>
Launch SFTP
</a>
</LinkButton>
</div>
</div>
</TitledGreyBox>
</div>
</Can>
<div className={'w-full mt-6 md:flex-1 md:max-w-1/2 md:mt-0'}>
<div css={tw`w-full mt-6 md:flex-1 md:mt-0`}>
<Can action={'settings.rename'}>
<div className={'mb-6 md:mb-10'}>
<div css={tw`mb-6 md:mb-10`}>
<RenameServerBox/>
</div>
</Can>