diff --git a/resources/assets/styles/components/animations.css b/resources/assets/styles/components/animations.css index d76279725..97c1ced7c 100644 --- a/resources/assets/styles/components/animations.css +++ b/resources/assets/styles/components/animations.css @@ -16,4 +16,13 @@ @apply .opacity-0; transition: opacity 150ms; } + +/** @todo fix this, hides footer stuff */ +div.route-transition-group { + @apply .relative; + + & section { + @apply .absolute .w-full .pin-t .pin-l; + } +} /*! purgecss end ignore */ diff --git a/resources/scripts/api/auth/requestPasswordResetEmail.ts b/resources/scripts/api/auth/requestPasswordResetEmail.ts new file mode 100644 index 000000000..f456560bb --- /dev/null +++ b/resources/scripts/api/auth/requestPasswordResetEmail.ts @@ -0,0 +1,9 @@ +import http from '@/api/http'; + +export default (email: string): Promise => { + return new Promise((resolve, reject) => { + http.post('/auth/password', { email }) + .then(() => resolve()) + .catch(reject); + }); +}; diff --git a/resources/scripts/api/http.ts b/resources/scripts/api/http.ts index 1c8359d97..676a735c7 100644 --- a/resources/scripts/api/http.ts +++ b/resources/scripts/api/http.ts @@ -9,6 +9,7 @@ const http: AxiosInstance = axios.create({ 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json', 'Content-Type': 'application/json', + 'X-CSRF-Token': (window as any).X_CSRF_TOKEN as string || '', }, }); diff --git a/resources/scripts/components/auth/ForgotPasswordContainer.tsx b/resources/scripts/components/auth/ForgotPasswordContainer.tsx new file mode 100644 index 000000000..f41de737b --- /dev/null +++ b/resources/scripts/components/auth/ForgotPasswordContainer.tsx @@ -0,0 +1,75 @@ +import * as React from 'react'; +import OpenInputField from '@/components/forms/OpenInputField'; +import { Link } from 'react-router-dom'; +import requestPasswordResetEmail from '@/api/auth/requestPasswordResetEmail'; + +type Props = Readonly<{ + +}>; + +type State = Readonly<{ + email: string; + isSubmitting: boolean; +}>; + +export default class ForgotPasswordContainer extends React.PureComponent { + state: State = { + email: '', + isSubmitting: false, + }; + + handleFieldUpdate = (e: React.ChangeEvent) => this.setState({ + email: e.target.value, + }); + + handleSubmission = (e: React.FormEvent) => this.setState({ isSubmitting: true }, () => { + e.preventDefault(); + + requestPasswordResetEmail(this.state.email) + .then(() => { + + }) + .catch(console.error) + .then(() => this.setState({ isSubmitting: false })); + }); + + render () { + return ( + +
+
+ +
+
+ +
+
+ + Return to Login + +
+
+
+ ); + } +} diff --git a/resources/scripts/components/auth/LoginContainer.tsx b/resources/scripts/components/auth/LoginContainer.tsx index db0b947fa..3ccae9923 100644 --- a/resources/scripts/components/auth/LoginContainer.tsx +++ b/resources/scripts/components/auth/LoginContainer.tsx @@ -98,7 +98,7 @@ export default class LoginContainer extends React.PureComponent<{}, State> {
Forgot password? diff --git a/resources/scripts/components/forms/OpenInputField.tsx b/resources/scripts/components/forms/OpenInputField.tsx index 0f7e2603b..92161ef21 100644 --- a/resources/scripts/components/forms/OpenInputField.tsx +++ b/resources/scripts/components/forms/OpenInputField.tsx @@ -3,9 +3,10 @@ import classNames from 'classnames'; type Props = React.InputHTMLAttributes & { label: string; + description?: string; }; -export default ({ className, onChange, label, ...props }: Props) => { +export default ({ className, description, onChange, label, ...props }: Props) => { const [ value, setValue ] = React.useState(''); const classes = classNames('input open-label', { @@ -25,6 +26,11 @@ export default ({ className, onChange, label, ...props }: Props) => { {...props} /> + {description && +

+ {description} +

+ }
); }; diff --git a/resources/scripts/routers/AuthenticationRouter.tsx b/resources/scripts/routers/AuthenticationRouter.tsx index 45de3165c..c7d6b3ee6 100644 --- a/resources/scripts/routers/AuthenticationRouter.tsx +++ b/resources/scripts/routers/AuthenticationRouter.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; import { BrowserRouter, Route, Switch } from 'react-router-dom'; import LoginContainer from '@/components/auth/LoginContainer'; import { CSSTransition, TransitionGroup } from 'react-transition-group'; +import ForgotPasswordContainer from '@/components/auth/ForgotPasswordContainer'; export default class AuthenticationRouter extends React.PureComponent { render () { @@ -9,13 +10,24 @@ export default class AuthenticationRouter extends React.PureComponent { ( - + - - - - - +
+ + + + + +

+ © 2015 - 2019  + + Pterodactyl Software + +

+
)} diff --git a/resources/themes/pterodactyl/templates/auth/core.blade.php b/resources/themes/pterodactyl/templates/auth/core.blade.php index da27fcc95..6c106020b 100644 --- a/resources/themes/pterodactyl/templates/auth/core.blade.php +++ b/resources/themes/pterodactyl/templates/auth/core.blade.php @@ -5,8 +5,5 @@ @section('container')
-

- {!! trans('strings.copyright', ['year' => date('Y')]) !!} -

@endsection