Skip to content

Commit

Permalink
Merge pull request #137 from AutomatingSciencePipeline/frontend-compo…
Browse files Browse the repository at this point in the history
…nentization

Sign In feedback + Frontend componentization
  • Loading branch information
budak7273 authored Feb 9, 2023
2 parents b9ff621 + eb5ada5 commit 059726d
Show file tree
Hide file tree
Showing 12 changed files with 614 additions and 405 deletions.
2 changes: 2 additions & 0 deletions .devcontainer/post-start.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#!/bin/bash

# Silence warnings about the git repos not being owned by this user (since it's bind mounted from host)
# This runs inside the container, so it's okay to do global git config
git config --global --add safe.directory "/workspaces/Monorepo"
Expand Down
1 change: 1 addition & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"wix.vscode-import-cost",
"jock.svg",
"herrmannplatz.npm-dependency-links",
"doggy8088.quicktype-refresh",

// Backend
"KevinRose.vsc-python-indent",
Expand Down
2 changes: 1 addition & 1 deletion Monorepo.wiki
1 change: 1 addition & 0 deletions apps/backend/backend.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ RUN pip install pipenv
COPY Pipfile .
COPY Pipfile.lock .
# Args explanation: https://stackoverflow.com/a/49705601
# https://pipenv-fork.readthedocs.io/en/latest/basics.html#pipenv-install
RUN pipenv install --system --deploy --ignore-pipfile

WORKDIR /app
Expand Down
68 changes: 68 additions & 0 deletions apps/frontend/components/auth/AlreadySignedInModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import Link from 'next/link';
import Router from 'next/router';
import { useAuth } from '../../firebase/fbAuth';

export interface AlreadySignedInModalProps {
continueButtonMessage: string,
linkTarget: string
}

export const AlreadySignedInModal = ({ continueButtonMessage, linkTarget }: AlreadySignedInModalProps) => {
const { authService } = useAuth();

return <div className='mt-16 sm:mt-24 lg:mt-0 lg:col-span-6'>
<div className='bg-white sm:max-w-md sm:w-full sm:mx-auto sm:rounded-lg sm:overflow-hidden'>
<div className='px-4 py-8 sm:px-10'>
<div>
<p className='text-sm font-medium text-gray-700'>
{"You're already signed in as"}
</p>
<span className='px-2 bg-white text-gray-500'>
{authService.userEmail}
</span>
</div>

<div className='mt-3'>
<Link href={linkTarget}>
<a
className='space-x-6 flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500'
>
{continueButtonMessage}
</a>
</Link>
</div>

<div className='mt-3 relative'>
<div
className='absolute inset-0 flex items-center'
aria-hidden='true'
>
<div className='w-full border-t border-gray-300' />
</div>
<div className='relative flex justify-center text-sm'>
<span className='px-2 bg-white text-gray-500'>
Or
</span>
</div>
</div>
<div className='mt-3'>
<a
className='space-x-6 flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500'
onClick={() => {
return (
authService
.signOut()
.then(() => {
Router.reload();
})
.catch((err) => console.log('Sign out error', err))
);
}}
>
Log Out
</a>
</div>
</div>
</div>
</div>;
};
217 changes: 217 additions & 0 deletions apps/frontend/components/auth/SignInModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
import { joiResolver, useForm } from '@mantine/form';
import Link from 'next/link';
import { useState } from 'react';
import { useAuth } from '../../firebase/fbAuth';
import { emailSchema, signInSchema } from '../../utils/validators';

export const DEFAULT_SIGN_IN_TEXT = 'Sign in';
export const SIGN_IN_LOADING_TEXT = 'Loading...';

export interface SignInModalProps {
afterSignIn: () => void
}

export const SignInModal = ({ afterSignIn }: SignInModalProps) => {
const form = useForm({
initialValues: {
email: '',
password: '',
},
schema: joiResolver(signInSchema),
});

const { authService } = useAuth();
const [buttonDisabled, setButtonDisabled] = useState(false);
const [buttonText, setButtonText] = useState(DEFAULT_SIGN_IN_TEXT);

return <div className='mt-8 sm:mx-auto sm:w-full sm:max-w-md'>
<div className='bg-white py-8 px-4 shadow sm:rounded-lg sm:px-10'>
<form
className='space-y-6'
onSubmit={form.onSubmit(async (values) => {
const { email, password } = values;
setButtonDisabled(true);
setButtonText(SIGN_IN_LOADING_TEXT);
await authService.signInWithEmailAndPassword(
email,
password
).then(() => {
afterSignIn();
}).catch((error) => {
alert(`Problem logging in: ${error}`);
setButtonText(DEFAULT_SIGN_IN_TEXT);
setButtonDisabled(false);
});
})}
>
<div>
<label
htmlFor='email'
className='block text-sm font-medium text-gray-700'
>
Email address
</label>
<div className='mt-1'>
<input
{...form.getInputProps('email')}
type='email'
autoComplete='email'
required
className='appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm' />
</div>
</div>

<div>
<label
htmlFor='password'
className='block text-sm font-medium text-gray-700'
>
Password
</label>
<div className='mt-1'>
<input
{...form.getInputProps('password')}
type='password'
autoComplete='current-password'
required
className='appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm' />
</div>
</div>

<div>
<button
type='submit'
disabled={buttonDisabled}
className='w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500'
>
{buttonText}
</button>
</div>

<div className='flex items-center justify-between'>
<div className='text-sm'>
<a
href='#'
className='font-medium text-blue-600 hover:text-blue-500'
onClick={async () => {
const entryEmail = form.getInputProps('email').value;
const { error: validationError, value: validatedEmail } = emailSchema.validate(entryEmail);
if (validationError) {
alert('Please enter a valid email address');
} else {
try {
await authService.sendPasswordResetEmail(validatedEmail);
alert('Password reset email sent');
} catch (error) {
alert(`Problem sending password reset email: ${error}`);
}
}
}}
>
Forgot your password?
</a>
</div>
</div>
</form>

<div className='mt-6'>
<div className='relative'>
<div className='absolute inset-0 flex items-center'>
<div className='w-full border-t border-gray-300' />
</div>
<div className='relative flex justify-center text-sm'>
<span className='px-2 bg-white text-gray-500'>
Or continue with
</span>
</div>
</div>

<span className='px-2 bg-white text-gray-500'>
(OAuth login support coming soon™)
</span>

{/* TODO implement OAuth sign in */}
{/* <div className='mt-6 grid grid-cols-3 gap-3'>
<div>
<a
href='#'
className='w-full inline-flex justify-center py-2 px-4 border border-gray-300 rounded-md shadow-sm bg-white text-sm font-medium text-gray-500 hover:bg-gray-50'
>
<span className='sr-only'>Sign in with Facebook</span>
<svg
className='w-5 h-5'
aria-hidden='true'
fill='currentColor'
viewBox='0 0 20 20'
>
<path
fillRule='evenodd'
d='M20 10c0-5.523-4.477-10-10-10S0 4.477 0 10c0 4.991 3.657 9.128 8.438 9.878v-6.987h-2.54V10h2.54V7.797c0-2.506 1.492-3.89 3.777-3.89 1.094 0 2.238.195 2.238.195v2.46h-1.26c-1.243 0-1.63.771-1.63 1.562V10h2.773l-.443 2.89h-2.33v6.988C16.343 19.128 20 14.991 20 10z'
clipRule='evenodd' />
</svg>
</a>
</div>
<div>
<a
href='#'
className='w-full inline-flex justify-center py-2 px-4 border border-gray-300 rounded-md shadow-sm bg-white text-sm font-medium text-gray-500 hover:bg-gray-50'
>
<span className='sr-only'>Sign in with Twitter</span>
<svg
className='w-5 h-5'
aria-hidden='true'
fill='currentColor'
viewBox='0 0 20 20'
>
<path d='M6.29 18.251c7.547 0 11.675-6.253 11.675-11.675 0-.178 0-.355-.012-.53A8.348 8.348 0 0020 3.92a8.19 8.19 0 01-2.357.646 4.118 4.118 0 001.804-2.27 8.224 8.224 0 01-2.605.996 4.107 4.107 0 00-6.993 3.743 11.65 11.65 0 01-8.457-4.287 4.106 4.106 0 001.27 5.477A4.073 4.073 0 01.8 7.713v.052a4.105 4.105 0 003.292 4.022 4.095 4.095 0 01-1.853.07 4.108 4.108 0 003.834 2.85A8.233 8.233 0 010 16.407a11.616 11.616 0 006.29 1.84' />
</svg>
</a>
</div>
<div>
<a
href='#'
className='w-full inline-flex justify-center py-2 px-4 border border-gray-300 rounded-md shadow-sm bg-white text-sm font-medium text-gray-500 hover:bg-gray-50'
>
<span className='sr-only'>Sign in with GitHub</span>
<svg
className='w-5 h-5'
aria-hidden='true'
fill='currentColor'
viewBox='0 0 20 20'
>
<path
fillRule='evenodd'
d='M10 0C4.477 0 0 4.484 0 10.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0110 4.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.203 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.942.359.31.678.921.678 1.856 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0020 10.017C20 4.484 15.522 0 10 0z'
clipRule='evenodd' />
</svg>
</a>
</div>
</div> */}
</div>
<div className='mt-3 relative'>
<div
className='absolute inset-0 flex items-center'
aria-hidden='true'
>
<div className='w-full border-t border-gray-300' />
</div>
<div className='relative flex justify-center text-sm'>
<span className='px-2 bg-white text-gray-500'>
No account yet?
</span>
</div>
</div>
<div className='mt-3'>
<Link href={'/'}>
<a
className='space-x-6 flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500'
>
Go to the Sign Up Page
</a>
</Link>
</div>
</div>
</div>;
};
Loading

0 comments on commit 059726d

Please sign in to comment.