Start working on some defined styles, begin implementing password update in account
This commit is contained in:
parent
0789b814dd
commit
adcd2682ef
8 changed files with 226 additions and 91 deletions
|
@ -15,19 +15,23 @@ input[type=number] {
|
|||
/**
|
||||
* Styling for other forms throughout the Panel.
|
||||
*/
|
||||
.input {
|
||||
@apply .appearance-none .p-3 .rounded .border .border-neutral-200 .text-neutral-800 .w-full;
|
||||
.input, .input-dark {
|
||||
@apply .appearance-none .w-full;
|
||||
min-width: 0;
|
||||
|
||||
&:required, &:invalid {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
.input {
|
||||
@apply .p-3 .rounded .border .border-neutral-200 .text-neutral-800;
|
||||
transition: border 150ms linear;
|
||||
|
||||
&:focus {
|
||||
@apply .border-primary-400;
|
||||
}
|
||||
|
||||
&:required, &:invalid {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
&.error {
|
||||
@apply .text-red-600 .border-red-500;
|
||||
}
|
||||
|
@ -37,6 +41,39 @@ input[type=number] {
|
|||
@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 {
|
||||
@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);
|
||||
}
|
||||
|
||||
.input-dark-label {
|
||||
@apply .uppercase .text-neutral-200;
|
||||
}
|
||||
|
||||
.input-label {
|
||||
@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 {
|
||||
@apply .no-underline;
|
||||
}
|
||||
|
||||
.btn {
|
||||
@apply .rounded .p-2;
|
||||
@apply .rounded .p-2 .uppercase .tracking-wide .text-sm;
|
||||
transition: all 150ms linear;
|
||||
|
||||
/**
|
||||
* Button Colors
|
||||
*/
|
||||
&.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) {
|
||||
@apply .bg-primary-600 .border-primary-800;
|
||||
@apply .bg-primary-600 .border-primary-700;
|
||||
}
|
||||
}
|
||||
|
||||
&.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) {
|
||||
@apply .bg-green-600 .border-green-800;
|
||||
@apply .bg-green-600 .border-green-700;
|
||||
}
|
||||
}
|
||||
|
||||
&.btn-red {
|
||||
&: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) {
|
||||
@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 {
|
||||
@apply .border .border-neutral-200 .text-neutral-400;
|
||||
@apply .border .border-neutral-600 .bg-transparent .text-neutral-200;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
@apply .border-neutral-500 .text-neutral-700;
|
||||
@apply .border-neutral-500 .text-neutral-100;
|
||||
}
|
||||
|
||||
&.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
|
||||
*/
|
||||
&.btn-jumbo {
|
||||
@apply .p-4 .w-full .uppercase .tracking-wide .text-sm;
|
||||
@apply .p-4 .w-full;
|
||||
}
|
||||
|
||||
&.btn-lg {
|
||||
@apply .p-4 .uppercase .tracking-wide .text-sm;
|
||||
@apply .p-4 .text-sm;
|
||||
}
|
||||
|
||||
&.btn-sm {
|
||||
@apply .px-6 .py-3 .uppercase .tracking-wide .text-sm;
|
||||
@apply .p-3;
|
||||
}
|
||||
|
||||
&.btn-xs {
|
||||
@apply .py-2 .px-2 .uppercase .text-xs;
|
||||
@apply .p-2 .text-xs;
|
||||
}
|
||||
|
||||
&:disabled, &.disabled {
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
import * as React from 'react';
|
||||
|
||||
export default class AccountOverview extends React.PureComponent {
|
||||
render () {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -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>
|
||||
);
|
||||
};
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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>
|
||||
);
|
||||
};
|
18
resources/scripts/components/elements/ContentBox.tsx
Normal file
18
resources/scripts/components/elements/ContentBox.tsx
Normal 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>
|
||||
);
|
|
@ -1,10 +1,11 @@
|
|||
import * as React from 'react';
|
||||
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) => (
|
||||
<div>
|
||||
<Route path={`${match.path}/`} component={DesignElements} exact/>
|
||||
<Route path={`${match.path}/design`} component={DesignElements} exact/>
|
||||
<Route path={`${match.path}/`} component={AccountOverviewContainer} exact/>
|
||||
<Route path={`${match.path}/design`} component={DesignElementsContainer} exact/>
|
||||
</div>
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue