Skip to content

Commit

Permalink
feat(app-login): add login page
Browse files Browse the repository at this point in the history
  • Loading branch information
rams23 committed Jan 5, 2021
1 parent 6d661fb commit cd4270b
Show file tree
Hide file tree
Showing 11 changed files with 137 additions and 35 deletions.
3 changes: 2 additions & 1 deletion packages/game-app/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const Signup = React.lazy(() => import('./signup/components/Signup'));
const EmailVerificationRequired = React.lazy(() => import('./signup/components/EmailVerificationRequired'));
const VerifyEmail = React.lazy(() => import('./signup/components/VerifyEmail'));
const Dashboard = React.lazy(() => import('./dashboard/components/Dashboard'));
const Login = React.lazy(() => import('./login/components/Login'));

/**
* Returns route and default redirect according to auth condition:
Expand All @@ -19,7 +20,7 @@ const Dashboard = React.lazy(() => import('./dashboard/components/Dashboard'));
function renderAuthRoutes(user: AuthUser | null) {
if (!user) {
return [
<Route path={RoutingPath.Login} render={() => <div>Login</div>} />,
<Route path={RoutingPath.Login} component={Login} />,
<Route path={RoutingPath.Signup} component={Signup} />,
<Route path={RoutingPath.VerifyEmail} component={VerifyEmail} />,
<Route path="*">
Expand Down
4 changes: 4 additions & 0 deletions packages/game-app/src/_shared/auth/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ export const useResendVerificationEmail = createRequestHook(
export const useEmailVerification = createRequestHook('auth.emailVerification', actions.verifyEmail, {
errorMessagesScope: 'auth.errors',
});

export const useLogin = createRequestHook('auth.login', actions.login, {
errorMessagesScope: 'login.errors',
});
14 changes: 12 additions & 2 deletions packages/game-app/src/_shared/auth/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
import { reducer, actions, name, selectors, AuthUser } from './slice';
import saga from './saga';
import useLoggedUser from './useLoggedUser';
import { useEmailVerification, useResendVerificationEmail } from './hooks';
import { useEmailVerification, useLogin, useResendVerificationEmail } from './hooks';

export { reducer, actions, name, saga, selectors, useLoggedUser, useResendVerificationEmail, useEmailVerification };
export {
reducer,
actions,
name,
saga,
selectors,
useLoggedUser,
useResendVerificationEmail,
useEmailVerification,
useLogin,
};

export type { AuthUser };
16 changes: 16 additions & 0 deletions packages/game-app/src/_shared/auth/saga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,27 @@ function* executeEmailVerification(action: ReturnType<typeof actions.verifyEmail
}
}

function* executeLogin({ payload: { email, password } }: ReturnType<typeof actions.login>) {
const { user }: firebase.auth.UserCredential = yield call(() =>
firebase.auth().signInWithEmailAndPassword(email, password),
);
if (user) {
yield put(
actions.setLoggedUser({
emailVerified: user.emailVerified,
id: user.uid,
email: user.email!,
}),
);
}
}

export default function* authSaga() {
yield takeEvery(actions.initialize, initializeAuthSaga);
yield takeEvery(
actions.resendEmailVerification,
addRequestStatusManagement(resendVerificationEmail, 'auth.resendVerificationEmail'),
);
yield takeEvery(actions.verifyEmail, addRequestStatusManagement(executeEmailVerification, 'auth.emailVerification'));
yield takeEvery(actions.login, addRequestStatusManagement(executeLogin, 'auth.login'));
}
1 change: 1 addition & 0 deletions packages/game-app/src/_shared/auth/slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export const actions = {
...slice.actions,
resendEmailVerification: createAction(`${name}/resendEmailVerification`),
verifyEmail: createAction<{ code: string }>(`${name}/verifyEmail`),
login: createAction<{ email: string; password: string }>(`${name}/login`),
};
export const selectors = {
getCurrentUser,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export interface RequestsKeys {
devOpsMaturities: null;
'auth.resendVerificationEmail': null;
'auth.emailVerification': null;
'auth.login': null;
}
34 changes: 20 additions & 14 deletions packages/game-app/src/assets/i18n/en.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
const translations = {
home: {
title: 'Pipeline - The Game that Delivers!',
subtitle: 'Random stuff',
},
page2: {
test1: 'Pipeline - The Game that Delivers!',
test2: 'Random stuff',
},
auth: {
errors: {
'auth/invalid-action-code': 'Verification link invalid or already used',
},
},
dashboard: {
title: 'Pipeline',
subtitle: 'The Game that Delivers',
message:
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.',
},
login: {
title: 'Sign in to play',
form: {
emailLabel: 'Email',
passwordLabel: 'Password',
buttonText: 'Sign in',
},
errors: {
'auth/invalid-email': 'Email not valid',
'auth/user-disabled': 'User disabled',
'auth/user-not-found': 'Email or password invalid',
'auth/wrong-password': 'Email or password invalid',
},
},
signup: {
title: 'Signup to play',
verificationRequired: {
Expand All @@ -35,12 +47,6 @@ const translations = {
'auth/email-already-in-use': 'Ops, it seams that this email is not allowed',
},
},
dashboard: {
title: 'Pipeline',
subtitle: 'The Game that Delivers',
message:
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.',
},
general: {
errors: {
required: 'This field is required',
Expand Down
49 changes: 49 additions & 0 deletions packages/game-app/src/login/components/Login/Login.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React, { useMemo } from 'react';
import { useForm, FormProvider } from 'react-hook-form';
import { FormTextField } from '@pipeline/form';
import { PasswordInput } from '@pipeline/components';
import { useTranslate } from '@pipeline/i18n';
import { useLogin } from '@pipeline/auth';

type Props = {};

const Login: React.FC<Props> = () => {
const t = useTranslate();

const methods = useForm<{ email: string; password: string }>({
mode: 'onBlur',
defaultValues: {
email: '',
password: '',
},
});

const handleSubmit = methods.handleSubmit;

const { call, translatedError, loading } = useLogin();

const submit = useMemo(() => handleSubmit(call), [handleSubmit, call]);

return (
<div className="login">
<div className="content card">
<h2>{t('login.title')}</h2>
<FormProvider {...methods}>
<FormTextField name="email" label={t('login.form.emailLabel')} />
<FormTextField CustomInput={PasswordInput} name="password" label={t('login.form.passwordLabel')} />
<div className="text-center">
<button className="primary" onClick={submit}>
{t('login.form.buttonText')}
</button>
</div>
{translatedError ? <span className="error-message">{translatedError}</span> : null}
{loading ? <span>Loading</span> : null}
</FormProvider>
</div>
</div>
);
};

Login.displayName = 'Login';

export default Login;
3 changes: 3 additions & 0 deletions packages/game-app/src/login/components/Login/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Login from './Login';

export default Login;
36 changes: 19 additions & 17 deletions packages/game-app/src/signup/components/Signup/Signup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,24 +54,26 @@ const Signup: React.FC<Props> = () => {
<div className="content card">
<h2>{t('signup.title')}</h2>
<FormProvider {...methods}>
<FormTextField type="email" name="email" label={t('signup.form.emailLabel')} />
<FormTextField CustomInput={PasswordInput} name="password" label={t('signup.form.passwordLabel')} />
<FormTextField
CustomInput={PasswordInput}
name="repeatPassword"
label={t('signup.form.repeatPasswordLabel')}
/>
<FormSelect name="role" label={t('signup.form.roleLabel')} options={gameRoles} />
<FormSelect name="devOpsMaturity" label={t('signup.form.maturityLabel')} options={devOpsMaturities} />
<div className="text-center ">
<button className="primary" id="signup-button" onClick={submit}>
{t('signup.form.buttonText')}
</button>
</div>
<form>
<FormTextField type="email" name="email" label={t('signup.form.emailLabel')} />
<FormTextField CustomInput={PasswordInput} name="password" label={t('signup.form.passwordLabel')} />
<FormTextField
CustomInput={PasswordInput}
name="repeatPassword"
label={t('signup.form.repeatPasswordLabel')}
/>
<FormSelect name="role" label={t('signup.form.roleLabel')} options={gameRoles} />
<FormSelect name="devOpsMaturity" label={t('signup.form.maturityLabel')} options={devOpsMaturities} />
<div className="text-center ">
<button className="primary" id="signup-button" onClick={submit}>
{t('signup.form.buttonText')}
</button>
</div>

{signupLoading ? <span>Loading</span> : null}
{signupTranslateError ? <span className="error-message">{signupTranslateError}</span> : null}
{signupSuccess ? <span>Success</span> : null}
{signupLoading ? <span>Loading</span> : null}
{signupTranslateError ? <span className="error-message">{signupTranslateError}</span> : null}
{signupSuccess ? <span>Success</span> : null}
</form>
</FormProvider>
</div>
</div>
Expand Down
11 changes: 10 additions & 1 deletion packages/game-app/src/temporary.css
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,12 @@ input + button.icon-button {
}

/* signup */
.signup,
.login,
.dashboard {
display: inline-block;
width: 100%;
}

.content {
max-width: 350px;
Expand All @@ -177,17 +183,20 @@ input + button.icon-button {
height: 100vh;
width: 100vw;
background-color: white;
padding: 50px;
}

.dashboard h1 {
font-size: 70px;
margin-top: 50px;
margin-left: 50px;
}

.dashboard h2 {
font-size: 35px;
margin-left: 50px;
}
.dashboard h2 + p {
margin-top: 50px;
max-width: 450px;
margin-left: 50px;
}

0 comments on commit cd4270b

Please sign in to comment.