Update views to support a more logical container
This commit is contained in:
parent
e044e8db1c
commit
e6a61fbe9b
20 changed files with 85 additions and 39 deletions
1
public/assets/svgs/not_found.svg
Normal file
1
public/assets/svgs/not_found.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 6.8 KiB |
|
@ -1,7 +1,6 @@
|
|||
import React from 'react';
|
||||
import { Route } from 'react-router';
|
||||
import { CSSTransition, TransitionGroup } from 'react-transition-group';
|
||||
import PageContentBlock from '@/components/elements/PageContentBlock';
|
||||
|
||||
type Props = Readonly<{
|
||||
children: React.ReactNode;
|
||||
|
@ -13,9 +12,7 @@ export default ({ children }: Props) => (
|
|||
<TransitionGroup className={'route-transition-group'}>
|
||||
<CSSTransition key={location.key} timeout={250} in={true} appear={true} classNames={'fade'}>
|
||||
<section>
|
||||
<PageContentBlock>
|
||||
{children}
|
||||
</PageContentBlock>
|
||||
{children}
|
||||
</section>
|
||||
</CSSTransition>
|
||||
</TransitionGroup>
|
||||
|
|
|
@ -10,6 +10,7 @@ import { Provider } from 'react-redux';
|
|||
import { SiteSettings } from '@/state/settings';
|
||||
import { DefaultTheme, ThemeProvider } from 'styled-components';
|
||||
import ProgressBar from '@/components/elements/ProgressBar';
|
||||
import NotFound from '@/components/screens/NotFound';
|
||||
|
||||
interface ExtendedWindow extends Window {
|
||||
SiteConfiguration?: SiteSettings;
|
||||
|
@ -65,6 +66,7 @@ const App = () => {
|
|||
<Route path="/server/:id" component={ServerRouter}/>
|
||||
<Route path="/auth" component={AuthenticationRouter}/>
|
||||
<Route path="/" component={DashboardRouter}/>
|
||||
<Route path={'*'} component={NotFound}/>
|
||||
</Switch>
|
||||
</BrowserRouter>
|
||||
</div>
|
||||
|
|
|
@ -13,6 +13,7 @@ import { ApplicationStore } from '@/state';
|
|||
import FlashMessageRender from '@/components/FlashMessageRender';
|
||||
import { httpErrorToHuman } from '@/api/http';
|
||||
import format from 'date-fns/format';
|
||||
import PageContentBlock from '@/components/elements/PageContentBlock';
|
||||
|
||||
export default () => {
|
||||
const [ deleteIdentifier, setDeleteIdentifier ] = useState('');
|
||||
|
@ -46,7 +47,7 @@ export default () => {
|
|||
};
|
||||
|
||||
return (
|
||||
<div className={'my-10'}>
|
||||
<PageContentBlock>
|
||||
<FlashMessageRender byKey={'account'} className={'mb-4'}/>
|
||||
<div className={'flex'}>
|
||||
<ContentBox title={'Create API Key'} className={'flex-1'}>
|
||||
|
@ -107,6 +108,6 @@ export default () => {
|
|||
}
|
||||
</ContentBox>
|
||||
</div>
|
||||
</div>
|
||||
</PageContentBlock>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -5,6 +5,7 @@ import UpdateEmailAddressForm from '@/components/dashboard/forms/UpdateEmailAddr
|
|||
import ConfigureTwoFactorForm from '@/components/dashboard/forms/ConfigureTwoFactorForm';
|
||||
import styled from 'styled-components';
|
||||
import { breakpoint } from 'styled-components-breakpoint';
|
||||
import PageContentBlock from '@/components/elements/PageContentBlock';
|
||||
|
||||
const Container = styled.div`
|
||||
${tw`flex flex-wrap my-10`};
|
||||
|
@ -24,16 +25,22 @@ const Container = styled.div`
|
|||
|
||||
export default () => {
|
||||
return (
|
||||
<Container>
|
||||
<ContentBox title={'Update Password'} showFlashes={'account:password'}>
|
||||
<UpdatePasswordForm/>
|
||||
</ContentBox>
|
||||
<ContentBox className={'mt-8 md:mt-0 md:ml-8'} title={'Update Email Address'} showFlashes={'account:email'}>
|
||||
<UpdateEmailAddressForm/>
|
||||
</ContentBox>
|
||||
<ContentBox className={'xl:ml-8 mt-8 xl:mt-0'} title={'Configure Two Factor'}>
|
||||
<ConfigureTwoFactorForm/>
|
||||
</ContentBox>
|
||||
</Container>
|
||||
<PageContentBlock>
|
||||
<Container>
|
||||
<ContentBox title={'Update Password'} showFlashes={'account:password'}>
|
||||
<UpdatePasswordForm/>
|
||||
</ContentBox>
|
||||
<ContentBox
|
||||
className={'mt-8 md:mt-0 md:ml-8'}
|
||||
title={'Update Email Address'}
|
||||
showFlashes={'account:email'}
|
||||
>
|
||||
<UpdateEmailAddressForm/>
|
||||
</ContentBox>
|
||||
<ContentBox className={'xl:ml-8 mt-8 xl:mt-0'} title={'Configure Two Factor'}>
|
||||
<ConfigureTwoFactorForm/>
|
||||
</ContentBox>
|
||||
</Container>
|
||||
</PageContentBlock>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -3,6 +3,7 @@ import { Server } from '@/api/server/getServer';
|
|||
import getServers from '@/api/getServers';
|
||||
import ServerRow from '@/components/dashboard/ServerRow';
|
||||
import Spinner from '@/components/elements/Spinner';
|
||||
import PageContentBlock from '@/components/elements/PageContentBlock';
|
||||
|
||||
export default () => {
|
||||
const [ servers, setServers ] = useState<null | Server[]>(null);
|
||||
|
@ -18,7 +19,7 @@ export default () => {
|
|||
}
|
||||
|
||||
return (
|
||||
<div className={'my-10'}>
|
||||
<PageContentBlock>
|
||||
{servers.length > 0 ?
|
||||
servers.map(server => (
|
||||
<ServerRow key={server.uuid} server={server} className={'mt-2'}/>
|
||||
|
@ -28,6 +29,6 @@ export default () => {
|
|||
It looks like you have no servers.
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</PageContentBlock>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -4,12 +4,13 @@ import { CSSTransition } from 'react-transition-group';
|
|||
|
||||
interface Props {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export default ({ children }: Props) => (
|
||||
export default ({ className, children }: Props) => (
|
||||
<CSSTransition timeout={250} classNames={'fade'} appear={true} in={true}>
|
||||
<>
|
||||
<ContentContainer className={'my-10'}>
|
||||
<ContentContainer className={`my-10 ${className}`}>
|
||||
{children}
|
||||
</ContentContainer>
|
||||
<ContentContainer className={'mb-4'}>
|
||||
|
|
21
resources/scripts/components/screens/NotFound.tsx
Normal file
21
resources/scripts/components/screens/NotFound.tsx
Normal file
|
@ -0,0 +1,21 @@
|
|||
import React from 'react';
|
||||
import PageContentBlock from '@/components/elements/PageContentBlock';
|
||||
|
||||
interface Props {
|
||||
title?: string;
|
||||
message: string;
|
||||
}
|
||||
|
||||
export default ({ title, message }: Props) => (
|
||||
<PageContentBlock>
|
||||
<div className={'flex justify-center'}>
|
||||
<div className={'w-full sm:w-3/4 md:w-1/2 p-12 md:p-20 bg-neutral-100 rounded-lg shadow-lg text-center'}>
|
||||
<img src={'/assets/svgs/not_found.svg'} className={'w-2/3 h-auto select-none'}/>
|
||||
<h2 className={'mt-6 text-neutral-900 font-bold'}>404</h2>
|
||||
<p className={'text-sm text-neutral-700 mt-2'}>
|
||||
The requested resource was not found.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</PageContentBlock>
|
||||
);
|
|
@ -11,6 +11,7 @@ import { bytesToHuman } from '@/helpers';
|
|||
import SuspenseSpinner from '@/components/elements/SuspenseSpinner';
|
||||
import TitledGreyBox from '@/components/elements/TitledGreyBox';
|
||||
import Can from '@/components/elements/Can';
|
||||
import PageContentBlock from '@/components/elements/PageContentBlock';
|
||||
|
||||
type PowerAction = 'start' | 'stop' | 'restart' | 'kill';
|
||||
|
||||
|
@ -80,7 +81,7 @@ export default () => {
|
|||
}, [ instance, connected ]);
|
||||
|
||||
return (
|
||||
<div className={'my-10 flex'}>
|
||||
<PageContentBlock className={'flex'}>
|
||||
<div className={'w-1/4'}>
|
||||
<TitledGreyBox title={server.name} icon={faServer}>
|
||||
<p className={'text-xs uppercase'}>
|
||||
|
@ -159,6 +160,6 @@ export default () => {
|
|||
<ChunkedStatGraphs/>
|
||||
</SuspenseSpinner>
|
||||
</div>
|
||||
</div>
|
||||
</PageContentBlock>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@ import CreateBackupButton from '@/components/server/backups/CreateBackupButton';
|
|||
import FlashMessageRender from '@/components/FlashMessageRender';
|
||||
import BackupRow from '@/components/server/backups/BackupRow';
|
||||
import { ServerContext } from '@/state/server';
|
||||
import PageContentBlock from '@/components/elements/PageContentBlock';
|
||||
|
||||
export default () => {
|
||||
const { uuid } = useServer();
|
||||
|
@ -34,7 +35,7 @@ export default () => {
|
|||
}
|
||||
|
||||
return (
|
||||
<div className={'mt-10 mb-6'}>
|
||||
<PageContentBlock>
|
||||
<FlashMessageRender byKey={'backups'} className={'mb-4'}/>
|
||||
{!backups.length ?
|
||||
<p className="text-center text-sm text-neutral-400">
|
||||
|
@ -54,6 +55,6 @@ export default () => {
|
|||
<CreateBackupButton/>
|
||||
</div>
|
||||
</Can>
|
||||
</div>
|
||||
</PageContentBlock>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -10,6 +10,7 @@ import CreateDatabaseButton from '@/components/server/databases/CreateDatabaseBu
|
|||
import Can from '@/components/elements/Can';
|
||||
import useFlash from '@/plugins/useFlash';
|
||||
import useServer from '@/plugins/useServer';
|
||||
import PageContentBlock from '@/components/elements/PageContentBlock';
|
||||
|
||||
export default () => {
|
||||
const { uuid, featureLimits } = useServer();
|
||||
|
@ -33,7 +34,7 @@ export default () => {
|
|||
}, []);
|
||||
|
||||
return (
|
||||
<div className={'my-10 mb-6'}>
|
||||
<PageContentBlock>
|
||||
<FlashMessageRender byKey={'databases'} className={'mb-4'}/>
|
||||
{(!databases.length && loading) ?
|
||||
<Spinner size={'large'} centered={true}/>
|
||||
|
@ -67,6 +68,6 @@ export default () => {
|
|||
</>
|
||||
</CSSTransition>
|
||||
}
|
||||
</div>
|
||||
</PageContentBlock>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -12,6 +12,7 @@ import { useParams } from 'react-router';
|
|||
import FileNameModal from '@/components/server/files/FileNameModal';
|
||||
import Can from '@/components/elements/Can';
|
||||
import FlashMessageRender from '@/components/FlashMessageRender';
|
||||
import PageContentBlock from '@/components/elements/PageContentBlock';
|
||||
|
||||
const LazyAceEditor = lazy(() => import(/* webpackChunkName: "editor" */'@/components/elements/AceEditor'));
|
||||
|
||||
|
@ -67,7 +68,7 @@ export default () => {
|
|||
};
|
||||
|
||||
return (
|
||||
<div className={'mt-10 mb-4'}>
|
||||
<PageContentBlock>
|
||||
<FlashMessageRender byKey={'files:view'} className={'mb-4'}/>
|
||||
<FileManagerBreadcrumbs withinFileEditor={true} isNewFile={action !== 'edit'}/>
|
||||
<FileNameModal
|
||||
|
@ -104,6 +105,6 @@ export default () => {
|
|||
</Can>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</PageContentBlock>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -12,6 +12,7 @@ import { FileObject } from '@/api/server/files/loadDirectory';
|
|||
import NewDirectoryButton from '@/components/server/files/NewDirectoryButton';
|
||||
import { Link } from 'react-router-dom';
|
||||
import Can from '@/components/elements/Can';
|
||||
import PageContentBlock from '@/components/elements/PageContentBlock';
|
||||
|
||||
const sortFiles = (files: FileObject[]): FileObject[] => {
|
||||
return files.sort((a, b) => a.name.localeCompare(b.name))
|
||||
|
@ -38,7 +39,7 @@ export default () => {
|
|||
}, []);
|
||||
|
||||
return (
|
||||
<div className={'my-10 mb-6'}>
|
||||
<PageContentBlock>
|
||||
<FlashMessageRender byKey={'files'} className={'mb-4'}/>
|
||||
<React.Fragment>
|
||||
<FileManagerBreadcrumbs/>
|
||||
|
@ -92,6 +93,6 @@ export default () => {
|
|||
</React.Fragment>
|
||||
}
|
||||
</React.Fragment>
|
||||
</div>
|
||||
</PageContentBlock>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -10,6 +10,7 @@ import EditScheduleModal from '@/components/server/schedules/EditScheduleModal';
|
|||
import Can from '@/components/elements/Can';
|
||||
import useServer from '@/plugins/useServer';
|
||||
import useFlash from '@/plugins/useFlash';
|
||||
import PageContentBlock from '@/components/elements/PageContentBlock';
|
||||
|
||||
export default ({ match, history }: RouteComponentProps) => {
|
||||
const { uuid } = useServer();
|
||||
|
@ -32,7 +33,7 @@ export default ({ match, history }: RouteComponentProps) => {
|
|||
}, []);
|
||||
|
||||
return (
|
||||
<div className={'my-10 mb-6'}>
|
||||
<PageContentBlock>
|
||||
<FlashMessageRender byKey={'schedules'} className={'mb-4'}/>
|
||||
{(!schedules.length && loading) ?
|
||||
<Spinner size={'large'} centered={true}/>
|
||||
|
@ -76,6 +77,6 @@ export default ({ match, history }: RouteComponentProps) => {
|
|||
</Can>
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
</PageContentBlock>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -14,6 +14,7 @@ import Can from '@/components/elements/Can';
|
|||
import useServer from '@/plugins/useServer';
|
||||
import useFlash from '@/plugins/useFlash';
|
||||
import { ServerContext } from '@/state/server';
|
||||
import PageContentBlock from '@/components/elements/PageContentBlock';
|
||||
|
||||
interface Params {
|
||||
id: string;
|
||||
|
@ -49,7 +50,7 @@ export default ({ match, history, location: { state } }: RouteComponentProps<Par
|
|||
}, [ match ]);
|
||||
|
||||
return (
|
||||
<div className={'my-10 mb-6'}>
|
||||
<PageContentBlock>
|
||||
<FlashMessageRender byKey={'schedules'} className={'mb-4'}/>
|
||||
{!schedule || isLoading ?
|
||||
<Spinner size={'large'} centered={true}/>
|
||||
|
@ -104,6 +105,6 @@ export default ({ match, history, location: { state } }: RouteComponentProps<Par
|
|||
</div>
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
</PageContentBlock>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -8,13 +8,14 @@ import RenameServerBox from '@/components/server/settings/RenameServerBox';
|
|||
import FlashMessageRender from '@/components/FlashMessageRender';
|
||||
import Can from '@/components/elements/Can';
|
||||
import ReinstallServerBox from '@/components/server/settings/ReinstallServerBox';
|
||||
import PageContentBlock from '@/components/elements/PageContentBlock';
|
||||
|
||||
export default () => {
|
||||
const user = useStoreState<ApplicationStore, UserData>(state => state.user.data!);
|
||||
const server = ServerContext.useStoreState(state => state.server.data!);
|
||||
|
||||
return (
|
||||
<div className={'my-10 mb-6'}>
|
||||
<PageContentBlock>
|
||||
<FlashMessageRender byKey={'settings'} className={'mb-4'}/>
|
||||
<div className={'md:flex'}>
|
||||
<Can action={'file.sftp'}>
|
||||
|
@ -69,6 +70,6 @@ export default () => {
|
|||
</Can>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</PageContentBlock>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@ import FlashMessageRender from '@/components/FlashMessageRender';
|
|||
import getServerSubusers from '@/api/server/users/getServerSubusers';
|
||||
import { httpErrorToHuman } from '@/api/http';
|
||||
import Can from '@/components/elements/Can';
|
||||
import PageContentBlock from '@/components/elements/PageContentBlock';
|
||||
|
||||
export default () => {
|
||||
const [ loading, setLoading ] = useState(true);
|
||||
|
@ -46,7 +47,7 @@ export default () => {
|
|||
}
|
||||
|
||||
return (
|
||||
<div className={'mt-10 mb-6'}>
|
||||
<PageContentBlock>
|
||||
<FlashMessageRender byKey={'users'} className={'mb-4'}/>
|
||||
{!subusers.length ?
|
||||
<p className={'text-center text-sm text-neutral-400'}>
|
||||
|
@ -62,6 +63,6 @@ export default () => {
|
|||
<AddSubuserButton/>
|
||||
</div>
|
||||
</Can>
|
||||
</div>
|
||||
</PageContentBlock>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -4,6 +4,7 @@ import LoginContainer from '@/components/auth/LoginContainer';
|
|||
import ForgotPasswordContainer from '@/components/auth/ForgotPasswordContainer';
|
||||
import ResetPasswordContainer from '@/components/auth/ResetPasswordContainer';
|
||||
import LoginCheckpointContainer from '@/components/auth/LoginCheckpointContainer';
|
||||
import NotFound from '@/components/screens/NotFound';
|
||||
|
||||
export default ({ match }: RouteComponentProps) => (
|
||||
<div className={'mt-8 xl:mt-32'}>
|
||||
|
@ -12,5 +13,6 @@ export default ({ match }: RouteComponentProps) => (
|
|||
<Route path={`${match.path}/password`} component={ForgotPasswordContainer} exact/>
|
||||
<Route path={`${match.path}/password/reset/:token`} component={ResetPasswordContainer}/>
|
||||
<Route path={`${match.path}/checkpoint`}/>
|
||||
<Route path={'*'} component={NotFound}/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -6,6 +6,7 @@ import NavigationBar from '@/components/NavigationBar';
|
|||
import DashboardContainer from '@/components/dashboard/DashboardContainer';
|
||||
import TransitionRouter from '@/TransitionRouter';
|
||||
import AccountApiContainer from '@/components/dashboard/AccountApiContainer';
|
||||
import NotFound from '@/components/screens/NotFound';
|
||||
|
||||
export default ({ location }: RouteComponentProps) => (
|
||||
<React.Fragment>
|
||||
|
@ -24,6 +25,7 @@ export default ({ location }: RouteComponentProps) => (
|
|||
<Route path={'/account'} component={AccountOverviewContainer} exact/>
|
||||
<Route path={'/account/api'} component={AccountApiContainer} exact/>
|
||||
<Route path={'/design'} component={DesignElementsContainer}/>
|
||||
<Route path={'*'} component={NotFound}/>
|
||||
</Switch>
|
||||
</TransitionRouter>
|
||||
</React.Fragment>
|
||||
|
|
|
@ -20,6 +20,7 @@ import Spinner from '@/components/elements/Spinner';
|
|||
import ServerInstalling from '@/components/screens/ServerInstalling';
|
||||
import ServerError from '@/components/screens/ServerError';
|
||||
import { httpErrorToHuman } from '@/api/http';
|
||||
import NotFound from '@/components/screens/NotFound';
|
||||
|
||||
const ServerRouter = ({ match, location }: RouteComponentProps<{ id: string }>) => {
|
||||
const [ error, setError ] = useState('');
|
||||
|
@ -110,6 +111,7 @@ const ServerRouter = ({ match, location }: RouteComponentProps<{ id: string }>)
|
|||
<Route path={`${match.path}/users`} component={UsersContainer} exact/>
|
||||
<Route path={`${match.path}/backups`} component={BackupContainer} exact/>
|
||||
<Route path={`${match.path}/settings`} component={SettingsContainer} exact/>
|
||||
<Route path={'*'} component={NotFound}/>
|
||||
</Switch>
|
||||
</TransitionRouter>
|
||||
</>
|
||||
|
|
Loading…
Reference in a new issue