Skip to content

Commit 8c20158

Browse files
committed
Fix login form
1 parent 02f83c5 commit 8c20158

File tree

6 files changed

+106
-64
lines changed

6 files changed

+106
-64
lines changed
Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,22 @@
11
import React from 'react';
22
import MessageBox from '@/components/MessageBox';
3-
import { State, useStoreState } from 'easy-peasy';
4-
import { ApplicationStore } from '@/state';
3+
import { useStoreState } from 'easy-peasy';
54
import tw from 'twin.macro';
65

76
type Props = Readonly<{
87
byKey?: string;
8+
className?: string;
99
}>;
1010

11-
export default ({ byKey }: Props) => {
12-
const flashes = useStoreState((state: State<ApplicationStore>) => state.flashes.items);
13-
14-
let filtered = flashes;
15-
if (byKey) {
16-
filtered = flashes.filter(flash => flash.key === byKey);
17-
}
18-
19-
if (filtered.length === 0) {
20-
return null;
21-
}
11+
const FlashMessageRender = ({ byKey, className }: Props) => {
12+
const flashes = useStoreState(state => state.flashes.items.filter(
13+
flash => byKey ? flash.key === byKey : true,
14+
));
2215

2316
return (
24-
<div>
17+
<div className={className}>
2518
{
26-
filtered.map((flash, index) => (
19+
flashes.map((flash, index) => (
2720
<React.Fragment key={flash.id || flash.type + flash.message}>
2821
{index > 0 && <div css={tw`mt-2`}></div>}
2922
<MessageBox type={flash.type} title={flash.title}>
@@ -35,3 +28,5 @@ export default ({ byKey }: Props) => {
3528
</div>
3629
);
3730
};
31+
32+
export default FlashMessageRender;
Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import * as React from 'react';
2+
import tw, { TwStyle } from 'twin.macro';
3+
import styled from 'styled-components/macro';
24

35
export type FlashMessageType = 'success' | 'info' | 'warning' | 'error';
46

@@ -8,11 +10,60 @@ interface Props {
810
type?: FlashMessageType;
911
}
1012

11-
export default ({ title, children, type }: Props) => (
12-
<div className={`lg:inline-flex alert ${type}`} role={'alert'}>
13-
{title && <span className={'title'}>{title}</span>}
14-
<span className={'message'}>
13+
const styling = (type?: FlashMessageType): TwStyle | string => {
14+
switch (type) {
15+
case 'error':
16+
return tw`bg-red-600 border-red-800`;
17+
case 'info':
18+
return tw`bg-primary-600 border-primary-800`;
19+
case 'success':
20+
return tw`bg-green-600 border-green-800`;
21+
case 'warning':
22+
return tw`bg-yellow-600 border-yellow-800`;
23+
default:
24+
return '';
25+
}
26+
};
27+
28+
const getBackground = (type?: FlashMessageType): TwStyle | string => {
29+
switch (type) {
30+
case 'error':
31+
return tw`bg-red-500`;
32+
case 'info':
33+
return tw`bg-primary-500`;
34+
case 'success':
35+
return tw`bg-green-500`;
36+
case 'warning':
37+
return tw`bg-yellow-500`;
38+
default:
39+
return '';
40+
}
41+
};
42+
43+
const Container = styled.div<{ $type?: FlashMessageType }>`
44+
${tw`p-2 border items-center leading-normal rounded flex w-full text-sm text-white`};
45+
${props => styling(props.$type)};
46+
`;
47+
Container.displayName = 'MessageBox.Container';
48+
49+
const MessageBox = ({ title, children, type }: Props) => (
50+
<Container css={tw`lg:inline-flex`} $type={type} role={'alert'}>
51+
{title &&
52+
<span
53+
className={'title'}
54+
css={[
55+
tw`flex rounded-full uppercase px-2 py-1 text-xs font-bold mr-3 leading-none`,
56+
getBackground(type),
57+
]}
58+
>
59+
{title}
60+
</span>
61+
}
62+
<span css={tw`mr-2 text-left flex-auto`}>
1563
{children}
1664
</span>
17-
</div>
65+
</Container>
1866
);
67+
MessageBox.displayName = 'MessageBox';
68+
69+
export default MessageBox;

resources/scripts/components/auth/ForgotPasswordContainer.tsx

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import { ApplicationStore } from '@/state';
88
import Field from '@/components/elements/Field';
99
import { Formik, FormikHelpers } from 'formik';
1010
import { object, string } from 'yup';
11+
import tw from 'twin.macro';
12+
import Button from '@/components/elements/Button';
1113

1214
interface Values {
1315
email: string;
@@ -43,33 +45,30 @@ export default () => {
4345
{({ isSubmitting }) => (
4446
<LoginFormContainer
4547
title={'Request Password Reset'}
46-
className={'w-full flex'}
48+
css={tw`w-full flex`}
4749
>
4850
<Field
49-
light={true}
51+
light
5052
label={'Email'}
5153
description={'Enter your account email address to receive instructions on resetting your password.'}
5254
name={'email'}
5355
type={'email'}
5456
/>
55-
<div className={'mt-6'}>
56-
<button
57+
<div css={tw`mt-6`}>
58+
<Button
5759
type={'submit'}
58-
className={'btn btn-primary btn-jumbo flex justify-center'}
60+
size={'xlarge'}
5961
disabled={isSubmitting}
62+
isLoading={isSubmitting}
6063
>
61-
{isSubmitting ?
62-
<div className={'spinner-circle spinner-sm spinner-white'}></div>
63-
:
64-
'Send Email'
65-
}
66-
</button>
64+
Send Email
65+
</Button>
6766
</div>
68-
<div className={'mt-6 text-center'}>
67+
<div css={tw`mt-6 text-center`}>
6968
<Link
7069
type={'button'}
7170
to={'/auth/login'}
72-
className={'text-xs text-neutral-500 tracking-wide uppercase no-underline hover:text-neutral-700'}
71+
css={tw`text-xs text-neutral-500 tracking-wide uppercase no-underline hover:text-neutral-700`}
7372
>
7473
Return to Login
7574
</Link>

resources/scripts/components/auth/LoginContainer.tsx

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import { httpErrorToHuman } from '@/api/http';
1111
import { FlashMessage } from '@/state/flashes';
1212
import ReCAPTCHA from 'react-google-recaptcha';
1313
import Spinner from '@/components/elements/Spinner';
14+
import tw from 'twin.macro';
15+
import Button from '@/components/elements/Button';
1416

1517
type OwnProps = RouteComponentProps & {
1618
clearFlashes: ActionCreator<void>;
@@ -36,36 +38,29 @@ const LoginContainer = ({ isSubmitting, setFieldValue, values, submitForm, handl
3638
{ref.current && ref.current.render()}
3739
<LoginFormContainer
3840
title={'Login to Continue'}
39-
className={'w-full flex'}
41+
css={tw`w-full flex`}
4042
onSubmit={submit}
4143
>
42-
<label htmlFor={'username'}>Username or Email</label>
4344
<Field
4445
type={'text'}
46+
label={'Username or Email'}
4547
id={'username'}
4648
name={'username'}
47-
className={'input'}
49+
light
4850
/>
49-
<div className={'mt-6'}>
50-
<label htmlFor={'password'}>Password</label>
51+
<div css={tw`mt-6`}>
5152
<Field
5253
type={'password'}
54+
label={'Password'}
5355
id={'password'}
5456
name={'password'}
55-
className={'input'}
57+
light
5658
/>
5759
</div>
58-
<div className={'mt-6'}>
59-
<button
60-
type={'submit'}
61-
className={'btn btn-primary btn-jumbo'}
62-
>
63-
{isSubmitting ?
64-
<Spinner size={'small'} className={'mx-auto'}/>
65-
:
66-
'Login'
67-
}
68-
</button>
60+
<div css={tw`mt-6`}>
61+
<Button type={'submit'} size={'xlarge'} isLoading={isSubmitting}>
62+
Login
63+
</Button>
6964
</div>
7065
{recaptchaEnabled &&
7166
<ReCAPTCHA
@@ -80,10 +75,10 @@ const LoginContainer = ({ isSubmitting, setFieldValue, values, submitForm, handl
8075
onExpired={() => setFieldValue('recaptchaData', null)}
8176
/>
8277
}
83-
<div className={'mt-6 text-center'}>
78+
<div css={tw`mt-6 text-center`}>
8479
<Link
8580
to={'/auth/password'}
86-
className={'text-xs text-neutral-500 tracking-wide no-underline uppercase hover:text-neutral-600'}
81+
css={tw`text-xs text-neutral-500 tracking-wide no-underline uppercase hover:text-neutral-600`}
8782
>
8883
Forgot password?
8984
</Link>

resources/scripts/components/auth/LoginFormContainer.tsx

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { forwardRef } from 'react';
22
import { Form } from 'formik';
33
import styled from 'styled-components/macro';
4-
import { breakpoint } from 'styled-components-breakpoint';
4+
import { breakpoint } from '@/theme';
55
import FlashMessageRender from '@/components/FlashMessageRender';
66
import tw from 'twin.macro';
77

@@ -30,27 +30,29 @@ const Container = styled.div`
3030

3131
export default forwardRef<HTMLFormElement, Props>(({ title, ...props }, ref) => (
3232
<Container>
33-
{title && <h2 className={'text-center text-neutral-100 font-medium py-4'}>
33+
{title &&
34+
<h2 css={tw`text-3xl text-center text-neutral-100 font-medium py-4`}>
3435
{title}
35-
</h2>}
36-
<FlashMessageRender className={'mb-2 px-1'}/>
36+
</h2>
37+
}
38+
<FlashMessageRender css={tw`mb-2 px-1`}/>
3739
<Form {...props} ref={ref}>
38-
<div className={'md:flex w-full bg-white shadow-lg rounded-lg p-6 md:pl-0 mx-1'}>
39-
<div className={'flex-none select-none mb-6 md:mb-0 self-center'}>
40-
<img src={'/assets/svgs/pterodactyl.svg'} className={'block w-48 md:w-64 mx-auto'}/>
40+
<div css={tw`md:flex w-full bg-white shadow-lg rounded-lg p-6 md:pl-0 mx-1`}>
41+
<div css={tw`flex-none select-none mb-6 md:mb-0 self-center`}>
42+
<img src={'/assets/svgs/pterodactyl.svg'} css={tw`block w-48 md:w-64 mx-auto`}/>
4143
</div>
42-
<div className={'flex-1'}>
44+
<div css={tw`flex-1`}>
4345
{props.children}
4446
</div>
4547
</div>
4648
</Form>
47-
<p className={'text-center text-neutral-500 text-xs mt-4'}>
49+
<p css={tw`text-center text-neutral-500 text-xs mt-4`}>
4850
&copy; 2015 - 2020&nbsp;
4951
<a
50-
rel={'noopener nofollow'}
52+
rel={'noopener nofollow noreferrer'}
5153
href={'https://pterodactyl.io'}
5254
target={'_blank'}
53-
className={'no-underline text-neutral-500 hover:text-neutral-300'}
55+
css={tw`no-underline text-neutral-500 hover:text-neutral-300`}
5456
>
5557
Pterodactyl Software
5658
</a>

resources/scripts/components/elements/Input.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ const inputStyle = css<Props>`
2222
${tw`p-3 border rounded text-sm transition-all duration-150`};
2323
${tw`bg-neutral-600 border-neutral-500 hover:border-neutral-400 text-neutral-200 shadow-none`};
2424
25-
${props => props.hasError && tw`text-red-600 border-red-500 hover:border-red-600`};
2625
& + .input-help {
2726
${tw`mt-1 text-xs`};
2827
${props => props.hasError ? tw`text-red-400` : tw`text-neutral-400`};
@@ -41,6 +40,7 @@ const inputStyle = css<Props>`
4140
}
4241
4342
${props => props.isLight && light};
43+
${props => props.hasError && tw`text-red-600 border-red-500 hover:border-red-600`};
4444
`;
4545

4646
const Input = styled.input<Props>`${inputStyle}`;

0 commit comments

Comments
 (0)