Skip to content

Commit

Permalink
Change request (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
DukeManh authored and humphd committed Apr 16, 2021
1 parent 497b4f8 commit 0e95b4f
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 89 deletions.
2 changes: 2 additions & 0 deletions docker/production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ services:
- AUTH_URL=${AUTH_URL}
- POSTS_URL=${POSTS_URL}
- SEARCH_URL=${SEARCH_URL}
- FEED_DISCOVERY_URL=${FEED_DISCOVERY_URL}
container_name: 'telescope'
restart: unless-stopped
environment:
Expand All @@ -49,6 +50,7 @@ services:
- API_URL
- WEB_URL
- SEARCH_URL
- FEED_DISCOVERY_URL
- LOG_LEVEL
- FEED_URL
- FEED_URL_INTERVAL_MS
Expand Down
111 changes: 65 additions & 46 deletions src/web/src/components/SignUp/Forms/GitHubAccount.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
/* eslint-disable camelcase */
import { useEffect, useState } from 'react';
import { useEffect, useRef, useState } from 'react';
import Button from '@material-ui/core/Button';
import { createStyles, makeStyles, Theme } from '@material-ui/core';
import { connect } from 'formik';
import useSWR from 'swr';

import { SignUpForm } from '../../../interfaces';
import formModels from '../Schema/FormModel';
import { TextInput, CheckBoxInput } from '../FormFields';
import PostAvatar from '../../Posts/PostAvatar';

const { githubUsername, github: githubModel, githubOwnership } = formModels;
const { githubUsername, github, githubOwnership } = formModels;

const useStyles = makeStyles((theme: Theme) =>
createStyles({
Expand Down Expand Up @@ -56,7 +55,7 @@ const useStyles = makeStyles((theme: Theme) =>
inputsContainer: {
width: '100%',
display: 'grid',
gridTemplateColumns: '100%',
gridTemplateColumns: '80% 20%',
'& .MuiFormHelperText-root': {
fontSize: '0.9em',
color: 'black',
Expand All @@ -65,6 +64,22 @@ const useStyles = makeStyles((theme: Theme) =>
color: 'black',
},
},
button: {
height: '35px',
width: '50%',
alignSelf: 'center',
fontSize: '0.8em',
background: '#121D59',
color: '#A0D1FB',
marginLeft: '5%',
'&:hover': {
color: 'black',
border: '1px solid #121D59',
},
'&.Mui-disabled': {
backgroundColor: 'inherit',
},
},
avatarPreview: {
textAlign: 'center',
justifyItems: 'center',
Expand All @@ -89,52 +104,51 @@ const gitHubApiUrl = 'https://api.github.com/users';
const GitHubAccount = connect<{}, SignUpForm>((props) => {
const classes = useStyles();
const { values, setFieldValue } = props.formik;
const [username, setUsername] = useState(values.githubUsername);
const [inputTimeout, setInputTimeout] = useState(setTimeout(() => {}, 0));
const [validating, setValidating] = useState(false);
const [error, setError] = useState('');
const controllerRef = useRef<AbortController | null>();

const { data: github, error } = useSWR(
values.githubUsername ? `${gitHubApiUrl}/${values.githubUsername}` : null,
async (u) => {
const validateGit = async () => {
if (values.githubUsername) {
setValidating(true);
if (controllerRef.current) {
controllerRef.current.abort();
}
controllerRef.current = new AbortController();
try {
const response = await fetch(u);
const response = await fetch(`${gitHubApiUrl}/${values.githubUsername}`, {
signal: controllerRef.current?.signal,
});
if (!response.ok) {
throw new Error(response.statusText);
}
return response.json();
const res = await response.json();

setFieldValue('github', {
username: res.login,
avatarUrl: res.avatar_url,
});
setError('');
} catch (err) {
throw err;
console.error(err, 'Unable to get GitHub profile');

setError('Unable to get GitHub profile');
setFieldValue('github', {}, true);
} finally {
setValidating(false);
controllerRef.current = null;
}
} else {
setError('');
setFieldValue('github', {}, true);
}
);

const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setUsername(e.target.value);
clearTimeout(inputTimeout);

// Update githubUsername 1000ms after input change
setInputTimeout(
setTimeout(() => {
setFieldValue('githubUsername', e.target.value);
}, 1000)
);
};

useEffect(() => {
if (error) {
setFieldValue('github', {}, true);
}

if (github) {
setFieldValue(
'github',
{
username: github.login,
avatarUrl: github.avatar_url,
},
true
);
}
}, [github, error, setFieldValue]);
return () => {
controllerRef.current?.abort();
};
}, []);

return (
<div className={classes.root}>
Expand All @@ -147,15 +161,20 @@ const GitHubAccount = connect<{}, SignUpForm>((props) => {
label={githubUsername.label}
name={githubUsername.name}
error={!!error}
helperText={!!error && githubModel.invalidErrorMsg}
onChange={handleInputChange}
value={username}
helperText={error || github.invalidErrorMsg}
/>
<Button className={classes.button} onClick={validateGit} disabled={validating}>
Get profile
</Button>
</div>
{!error && github && (
{!error && (
<div className={classes.avatarPreview}>
<PostAvatar name={github.login} blog={github.avatar_url} img={github.avatar_url} />
<h2 className={classes.username}>{github.login}</h2>
<PostAvatar
name={values.github.username || values.displayName}
blog={values.github.avatarUrl}
img={values.github?.avatarUrl}
/>
<h2 className={classes.username}>{values.github.username}</h2>
</div>
)}
</div>
Expand Down
29 changes: 14 additions & 15 deletions src/web/src/components/SignUp/Forms/RSSFeeds.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState, useEffect } from 'react';
import { useState, useEffect, useRef } from 'react';
import { Button, createStyles, makeStyles, Theme } from '@material-ui/core';
import { connect } from 'formik';
import FormControl from '@material-ui/core/FormControl';
Expand Down Expand Up @@ -142,19 +142,18 @@ const RSSFeeds = connect<{}, SignUpForm>((props) => {
const [feedUrls, setFeedUrls] = useState<Array<string>>([]);
const [blogUrlError, setBlogUrlError] = useState('');
const [validating, setValidating] = useState(false);

// A controller to cancel undesired requests
const [controller, setController] = useState(new AbortController());
const controllerRef = useRef<AbortController | null>();

const validateBlog = async () => {
if (!errors.blogUrl && feedDiscoveryServiceUrl) {
if (!errors.blogUrl) {
try {
setValidating(true);
const abortController = new AbortController();
setController(abortController);
const signal = abortController.signal;
const response = await fetch(feedDiscoveryServiceUrl, {
signal,
if (controllerRef.current) {
controllerRef.current.abort();
}
controllerRef.current = new AbortController();
const response = await fetch(`${feedDiscoveryServiceUrl}`, {
signal: controllerRef.current?.signal,
method: 'post',
headers: {
Authorization: `bearer ${token}`,
Expand All @@ -164,19 +163,20 @@ const RSSFeeds = connect<{}, SignUpForm>((props) => {
blogUrl: values.blogUrl,
}),
});
console.log(values.blogUrl);
if (!response.ok) {
throw new Error(response.statusText);
}
const res = await response.json();

setBlogUrlError('');
setFeedUrls(res.feedUrls);
setValidating(false);
} catch (err) {
console.error(err, 'Unable to discover feeds');
setBlogUrlError(`Unable to find RSS link at ${values.blogUrl}`);

setBlogUrlError('Unable to discover feeds');
setFeedUrls([]);
} finally {
controllerRef.current = null;
setValidating(false);
}
} else {
Expand All @@ -197,9 +197,8 @@ const RSSFeeds = connect<{}, SignUpForm>((props) => {
validateBlog();
}

// Abort feed-discovery on component unmounting
return () => {
controller.abort();
controllerRef.current?.abort();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
Expand Down
3 changes: 0 additions & 3 deletions src/web/src/components/SignUp/Schema/FormModel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,16 @@ export default {
displayName: {
name: 'displayName',
label: 'Display Name',
invalidErrorMsg: 'Make sure display name contains 2-16 characters',
},
firstName: {
name: 'firstName',
label: 'First name',
requiredErrorMsg: 'First name is required',
invalidErrorMsg: 'Make sure first name contains 2-16 characters',
},
lastName: {
name: 'lastName',
label: 'Last name',
requiredErrorMsg: 'Last name is required',
invalidErrorMsg: 'Make sure last name contains 2-16 characters',
},
email: {
name: 'email',
Expand Down
23 changes: 5 additions & 18 deletions src/web/src/components/SignUp/Schema/FormSchema.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,15 @@ const {
blogOwnership,
} = formModels;

const validateLength = (min: number, max: number) => (val: string | undefined): boolean =>
!!val && val.length >= min && val.length <= max;

const validateCheckBox = (val: boolean | undefined) => !!val;

// Each signup step has one validation schema
export default [
// First step has no validation logic
Yup.object().shape({}),

Yup.object().shape({
[firstName.name]: Yup.string()
.required(`${firstName.requiredErrorMsg}`)
.test('len', firstName.invalidErrorMsg, validateLength(2, 16)),
[lastName.name]: Yup.string()
.required(`${lastName.requiredErrorMsg}`)
.test('len', lastName.invalidErrorMsg, validateLength(2, 16)),
[displayName.name]: Yup.string().test(
'len',
displayName.invalidErrorMsg,
validateLength(2, 16)
),
[firstName.name]: Yup.string().required(`${firstName.requiredErrorMsg}`),
[lastName.name]: Yup.string().required(`${lastName.requiredErrorMsg}`),
[displayName.name]: Yup.string(),
}),

Yup.object().shape({
Expand All @@ -49,7 +36,7 @@ export default [
[githubOwnership.name]: Yup.boolean().test(
'agreed',
githubOwnership.invalidErrorMsg,
validateCheckBox
(val) => !!val
),
}),

Expand All @@ -59,7 +46,7 @@ export default [
[blogOwnership.name]: Yup.boolean().test(
'agreed',
blogOwnership.invalidErrorMsg,
validateCheckBox
(val) => !!val
),
}),

Expand Down
12 changes: 5 additions & 7 deletions src/web/src/pages/signup.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { createStyles, makeStyles, Theme } from '@material-ui/core';
import { useState, useEffect } from 'react';

import Button from '@material-ui/core/Button';
import { Formik, Form, FormikHelpers } from 'formik';
import Button from '@material-ui/core/Button';

import useAuth from '../hooks/use-auth';
import Overview from '../components/SignUp/Forms/Overview';
Expand All @@ -15,7 +14,7 @@ import DynamicImage from '../components/DynamicImage';
import { SignUpForm } from '../interfaces';
import formModels from '../components/SignUp/Schema/FormModel';
import formSchema from '../components/SignUp/Schema/FormSchema';
import { usersServiceUrl, webUrl } from '../config';
import { usersServiceUrl } from '../config';

const {
firstName,
Expand Down Expand Up @@ -136,7 +135,7 @@ const SignUpPage = () => {
const [activeStep, setActiveStep] = useState<number>(0);
const currentSchema = formSchema[activeStep];
const { user, token, login } = useAuth();
const [loggedIn, setLoggedIn] = useState(false);
const [loggedIn, setLoggedIn] = useState(!!user);

const handleNext = () => {
setActiveStep(activeStep + 1);
Expand Down Expand Up @@ -164,6 +163,7 @@ const SignUpPage = () => {
github,
feeds,
};
// TODO Update register URL
const response = await fetch(`${usersServiceUrl}/${user?.id}`, {
method: 'post',
headers: {
Expand All @@ -174,14 +174,12 @@ const SignUpPage = () => {
});

if (!response.ok) {
alert('Unable to create account.');
throw new Error('Unable to post - create account');
throw new Error(response.statusText);
}
login();
return;
} catch (err) {
console.error(err, 'Unable to Post');
window.location.href = `${webUrl}`;
}
} else {
handleNext();
Expand Down

0 comments on commit 0e95b4f

Please sign in to comment.