Start working on some defined styles, begin implementing password update in account

This commit is contained in:
Dane Everitt 2019-06-22 18:53:50 -07:00
parent 0789b814dd
commit adcd2682ef
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
8 changed files with 226 additions and 91 deletions

View file

@ -15,19 +15,23 @@ input[type=number] {
/** /**
* Styling for other forms throughout the Panel. * Styling for other forms throughout the Panel.
*/ */
.input { .input, .input-dark {
@apply .appearance-none .p-3 .rounded .border .border-neutral-200 .text-neutral-800 .w-full; @apply .appearance-none .w-full;
min-width: 0; min-width: 0;
&:required, &:invalid {
box-shadow: none;
}
}
.input {
@apply .p-3 .rounded .border .border-neutral-200 .text-neutral-800;
transition: border 150ms linear; transition: border 150ms linear;
&:focus { &:focus {
@apply .border-primary-400; @apply .border-primary-400;
} }
&:required, &:invalid {
box-shadow: none;
}
&.error { &.error {
@apply .text-red-600 .border-red-500; @apply .text-red-600 .border-red-500;
} }
@ -37,6 +41,39 @@ input[type=number] {
@apply .bg-neutral-100 .border-neutral-200; @apply .bg-neutral-100 .border-neutral-200;
} }
.input + .input-help {
@apply .text-xs .text-neutral-400 .pt-2;
&.error {
@apply .text-red-600;
}
}
.input-dark {
@apply .p-3 .bg-neutral-600 .border .border-neutral-500 .text-sm .rounded .text-neutral-200;
transition: border 150ms linear, box-shaodw 150ms ease-in;
&:focus {
@apply .shadow;
}
& + .input-help {
@apply .text-xs .text-neutral-400 .mt-2
}
&.error {
@apply .text-red-100 .border-red-400;
}
&.error + .input-help {
@apply .text-red-400;
}
&:disabled {
@apply .opacity-75;
}
}
label { label {
@apply .block .text-xs .font-medium .uppercase .text-neutral-700 .mb-2; @apply .block .text-xs .font-medium .uppercase .text-neutral-700 .mb-2;
} }
@ -61,6 +98,10 @@ select:not(.appearance-none) {
background-position-x: calc(100% - 0.75rem); background-position-x: calc(100% - 0.75rem);
} }
.input-dark-label {
@apply .uppercase .text-neutral-200;
}
.input-label { .input-label {
@apply .block .uppercase .tracking-wide .text-neutral-800 .text-xs .font-bold; @apply .block .uppercase .tracking-wide .text-neutral-800 .text-xs .font-bold;
@ -69,60 +110,60 @@ select:not(.appearance-none) {
} }
} }
.input-help {
@apply .text-xs .text-neutral-400 .pt-2;
&.error {
@apply .text-red-600;
}
}
a.btn { a.btn {
@apply .no-underline; @apply .no-underline;
} }
.btn { .btn {
@apply .rounded .p-2; @apply .rounded .p-2 .uppercase .tracking-wide .text-sm;
transition: all 150ms linear; transition: all 150ms linear;
/** /**
* Button Colors * Button Colors
*/ */
&.btn-primary { &.btn-primary {
@apply .bg-primary-500 .border-primary-600 .border .text-white; @apply .bg-primary-500 .border-primary-600 .border .text-primary-50;
&:hover:not(:disabled) { &:hover:not(:disabled) {
@apply .bg-primary-600 .border-primary-800; @apply .bg-primary-600 .border-primary-700;
} }
} }
&.btn-green { &.btn-green {
@apply .bg-green-500 .border-green-600 .border .text-white; @apply .bg-green-500 .border-green-600 .border .text-green-50;
&:hover:not(:disabled) { &:hover:not(:disabled) {
@apply .bg-green-600 .border-green-800; @apply .bg-green-600 .border-green-700;
} }
} }
&.btn-red { &.btn-red {
&:not(.btn-secondary) { &:not(.btn-secondary) {
@apply .bg-red-500 .border-red-600 .border .text-white; @apply .bg-red-500 .border-red-600 .text-red-50;
} }
&:hover:not(:disabled) { &:hover:not(:disabled) {
@apply .bg-red-600 .border-red-800; @apply .bg-red-600 .border-red-700;
}
}
&.btn-grey {
@apply .border .border-neutral-600 .bg-neutral-500 .text-neutral-50;
&:hover:not(:disabled) {
@apply .bg-neutral-600 .border-neutral-700;
} }
} }
&.btn-secondary { &.btn-secondary {
@apply .border .border-neutral-200 .text-neutral-400; @apply .border .border-neutral-600 .bg-transparent .text-neutral-200;
&:hover:not(:disabled) { &:hover:not(:disabled) {
@apply .border-neutral-500 .text-neutral-700; @apply .border-neutral-500 .text-neutral-100;
} }
&.btn-red:hover:not(:disabled) { &.btn-red:hover:not(:disabled) {
@apply .bg-red-600 .border-red-800 .text-white; @apply .bg-red-500 .border-red-600 .text-red-50;
} }
} }
@ -130,19 +171,19 @@ a.btn {
* Button Sizes * Button Sizes
*/ */
&.btn-jumbo { &.btn-jumbo {
@apply .p-4 .w-full .uppercase .tracking-wide .text-sm; @apply .p-4 .w-full;
} }
&.btn-lg { &.btn-lg {
@apply .p-4 .uppercase .tracking-wide .text-sm; @apply .p-4 .text-sm;
} }
&.btn-sm { &.btn-sm {
@apply .px-6 .py-3 .uppercase .tracking-wide .text-sm; @apply .p-3;
} }
&.btn-xs { &.btn-xs {
@apply .py-2 .px-2 .uppercase .text-xs; @apply .p-2 .text-xs;
} }
&:disabled, &.disabled { &:disabled, &.disabled {

View file

@ -1,7 +0,0 @@
import * as React from 'react';
export default class AccountOverview extends React.PureComponent {
render () {
return null;
}
}

View file

@ -0,0 +1,19 @@
import * as React from 'react';
import ContentBox from '@/components/elements/ContentBox';
import UpdatePasswordForm from '@/components/account/forms/UpdatePasswordForm';
export default () => {
return (
<div className={'flex my-10'}>
<ContentBox className={'flex-1 mr-4'} title={'Update Password'}>
<UpdatePasswordForm/>
</ContentBox>
<div className={'flex-1 ml-4'}>
<ContentBox title={'Update Email Address'}>
</ContentBox>
<ContentBox title={'Update Identity'} className={'mt-8'}>
</ContentBox>
</div>
</div>
);
};

View file

@ -1,53 +0,0 @@
import * as React from 'react';
import { Link } from 'react-router-dom';
export default class DesignElements extends React.PureComponent {
render () {
return (
<div className={'my-10'}>
<div className={'flex'}>
<div className={'flex-1 mr-4'}>
<h2 className={'text-neutral-300 mb-2 px-4'}>A Special Announcement</h2>
<div className={'bg-neutral-700 p-4 rounded shadow-lg border-t-4 border-primary-400'}>
<p className={'text-neutral-200 text-sm'}>
Your demands have been received: Dark Mode will be default in Pterodactyl 0.8!
</p>
<p><Link to={'/'}>Back</Link></p>
</div>
</div>
<div className={'ml-4 flex-1'}>
<h2 className={'text-neutral-300 mb-2 px-4'}>Form Elements</h2>
<div className={'bg-neutral-700 p-4 rounded shadow-lg border-t-4 border-primary-400'}>
<label className={'uppercase text-neutral-200'}>Email</label>
<input
type={'text'}
className={'w-full p-3 bg-neutral-600 border border-neutral-500 hover:border-neutral-400 text-sm rounded text-neutral-200 focus:shadow'}
style={{
transition: 'border-color 150ms linear, box-shadow 150ms ease-in',
}}
/>
<p className={'text-xs text-neutral-400 mt-2'}>
This is some descriptive helper text to explain how things work.
</p>
<div className={'mt-6'}/>
<label className={'uppercase text-neutral-200'}>Textarea</label>
<textarea
className={'w-full p-3 h-10 bg-neutral-600 border border-neutral-500 hover:border-neutral-400 text-sm rounded text-neutral-200 focus:shadow'}
style={{
transition: 'border-color 150ms linear, box-shadow 150ms ease-in',
}}
></textarea>
<div className={'mt-6'}/>
<button className={'tracking-wide bg-primary-500 spacing-wide text-xs text-primary-50 rounded p-3 uppercase border border-primary-600'}>
Button
</button>
<button className={'ml-2 tracking-wide bg-neutral-500 spacing-wide text-xs text-neutral-50 rounded p-3 uppercase border border-neutral-600'}>
Secondary
</button>
</div>
</div>
</div>
</div>
);
}
}

View file

@ -0,0 +1,69 @@
import * as React from 'react';
import { Link } from 'react-router-dom';
import ContentBox from '@/components/elements/ContentBox';
export default class DesignElementsContainer extends React.PureComponent {
render () {
return (
<div className={'my-10'}>
<div className={'flex'}>
<ContentBox className={'flex-1 mr-4'} title={'A Special Announcement'} borderColor={'border-primary-400'}>
<p className={'text-neutral-200 text-sm'}>
Your demands have been received: Dark Mode will be default in Pterodactyl 0.8!
</p>
<p><Link to={'/'}>Back</Link></p>
</ContentBox>
<div className={'ml-4 flex-1'}>
<h2 className={'text-neutral-300 mb-2 px-4'}>Form Elements</h2>
<div className={'bg-neutral-700 p-4 rounded shadow-lg border-t-4 border-primary-400'}>
<label className={'uppercase text-neutral-200'}>Email</label>
<input type={'text'} className={'input-dark'}/>
<p className={'input-help'}>
This is some descriptive helper text to explain how things work.
</p>
<div className={'mt-6'}/>
<label className={'uppercase text-neutral-200'}>Username</label>
<input type={'text'} className={'input-dark error'}/>
<p className={'input-help'}>
This field has an error.
</p>
<div className={'mt-6'}/>
<label className={'uppercase text-neutral-200'}>Disabled Field</label>
<input type={'text'} className={'input-dark'} disabled={true}/>
<div className={'mt-6'}/>
<label className={'uppercase text-neutral-200'}>Textarea</label>
<textarea className={'input-dark h-32'}></textarea>
<div className={'mt-6'}/>
<button className={'btn btn-primary btn-sm'}>
Blue
</button>
<button className={'btn btn-grey btn-sm ml-2'}>
Grey
</button>
<button className={'btn btn-green btn-sm ml-2'}>
Green
</button>
<button className={'btn btn-red btn-sm ml-2'}>
Red
</button>
<div className={'mt-6'}/>
<button className={'btn btn-secondary btn-sm'}>
Secondary
</button>
<button className={'btn btn-secondary btn-red btn-sm ml-2'}>
Secondary Danger
</button>
<div className={'mt-6'}/>
<button className={'btn btn-primary btn-lg'}>
Large
</button>
<button className={'btn btn-primary btn-xs ml-2'}>
Tiny
</button>
</div>
</div>
</div>
</div>
);
}
}

View file

@ -0,0 +1,47 @@
import React, { useState } from 'react';
import { State, useStoreState } from 'easy-peasy';
import { ApplicationState } from '@/state/types';
export default () => {
const [ isLoading, setIsLoading ] = useState(false);
const user = useStoreState((state: State<ApplicationState>) => state.user.data);
if (!user) {
return null;
}
return (
<form className={'m-0'}>
<label htmlFor={'current_password'} className={'input-dark-label'}>Current Password</label>
<input
id={'current_password'}
type={'password'}
className={'input-dark'}
/>
<div className={'mt-6'}>
<label htmlFor={'new_password'} className={'input-dark-label'}>New Password</label>
<input
id={'new_password'}
type={'password'}
className={'input-dark'}
/>
<p className={'input-help'}>
Your new password must be at least 8 characters in length.
</p>
</div>
<div className={'mt-6'}>
<label htmlFor={'new_password_confirm'} className={'input-dark-label'}>Confirm New Password</label>
<input
id={'new_password_confirm'}
type={'password'}
className={'input-dark'}
/>
</div>
<div className={'mt-6'}>
<button className={'btn btn-primary btn-sm'} disabled={true}>
Update Password
</button>
</div>
</form>
);
};

View file

@ -0,0 +1,18 @@
import * as React from 'react';
import classNames from 'classnames';
type Props = Readonly<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> & {
title?: string;
borderColor?: string;
}>;
export default ({ title, borderColor, children, ...props }: Props) => (
<div {...props}>
{title && <h2 className={'text-neutral-300 mb-2 px-4'}>{title}</h2>}
<div className={classNames('bg-neutral-700 p-4 rounded shadow-lg', borderColor, {
'border-t-4': !!borderColor,
})}>
{children}
</div>
</div>
);

View file

@ -1,10 +1,11 @@
import * as React from 'react'; import * as React from 'react';
import { Route, RouteComponentProps } from 'react-router-dom'; import { Route, RouteComponentProps } from 'react-router-dom';
import DesignElements from '@/components/account/DesignElements'; import DesignElementsContainer from '@/components/account/DesignElementsContainer';
import AccountOverviewContainer from '@/components/account/AccountOverviewContainer';
export default ({ match }: RouteComponentProps) => ( export default ({ match }: RouteComponentProps) => (
<div> <div>
<Route path={`${match.path}/`} component={DesignElements} exact/> <Route path={`${match.path}/`} component={AccountOverviewContainer} exact/>
<Route path={`${match.path}/design`} component={DesignElements} exact/> <Route path={`${match.path}/design`} component={DesignElementsContainer} exact/>
</div> </div>
); );