Commit 8e472db1 authored by Sam Gluck's avatar Sam Gluck
Browse files

- Change Username field of User to Name;

- Reduce amount scrolled when moving to step 2 of sign up;
- Move Languages above Interests in step 2 of sign up;
- Add "Bio" field to step 1 of sign up and to the User type;
- Add "real" tags to the Interests section of sign up step 2;
parent d501c600
......@@ -8,8 +8,9 @@ import { NotificationType } from '../components/elements/Notification/Notificati
export const DUMMY_USER = {
__typename: 'User',
id: 0,
username: 'MoodlerJoe',
name: 'Moodler Joe',
email: 'moodlerjoe@example.com',
bio: 'I <3 Moodle',
emojiId: '',
role: '',
location: '',
......
export default `
type User {
id: Int!
username: String!
name: String!
email: String!
bio: String!
emojiId: String!
role: String!
location: String!
......
......@@ -100,8 +100,8 @@ export default withTheme(
top: '-2px'
}}
src={avatar}
alt={user.data.username}
title={`Hi, ${user.data.username}!`}
alt={user.data.name}
title={`Hi, ${user.data.name}!`}
/>
</Avatar>
</MenuNavItem>
......
......@@ -27,7 +27,7 @@ const UserMenu = styled.div`
export default ({ user }) => {
return (
<UserMenu>
<UserLink title="Go to Edit profile" to={`/user/${user.username}`}>
<UserLink title="Go to Edit profile" to={`/user`}>
<FontAwesomeIcon icon={faPencilAlt} /> &nbsp;Edit profile
</UserLink>
<br />
......
......@@ -4,7 +4,7 @@ query GetUserQuery {
isAuthenticated
data {
id
username
name
email
emojiId
role
......
......@@ -82,12 +82,12 @@ interface LoginState {
}
type CredentialsObject = {
username: string;
email: string;
password: string;
};
const DEMO_CREDENTIALS = {
username: 'moodle',
email: 'moodle@moodle.net',
password: 'moodle'
};
......@@ -101,11 +101,11 @@ class Login extends React.Component<LoginProps, LoginState> {
static validateCredentials(credentials: CredentialsObject) {
const validation: ValidationObject[] = [];
if (!credentials.username.length) {
if (!credentials.email.length) {
validation.push({
field: ValidationField.username,
field: ValidationField.email,
type: ValidationType.error,
message: 'The username field cannot be empty'
message: 'The email field cannot be empty'
} as ValidationObject);
}
if (!credentials.password.length) {
......@@ -144,7 +144,7 @@ class Login extends React.Component<LoginProps, LoginState> {
// TODO implement real auth when we know what the backend looks like
setTimeout(async () => {
if (
credentials.username !== DEMO_CREDENTIALS.username ||
credentials.email !== DEMO_CREDENTIALS.email ||
credentials.password !== DEMO_CREDENTIALS.password
) {
this.setState({
......
......@@ -38,13 +38,13 @@ type LoginFormProps = {
};
type LoginFormState = {
username: string;
email: string;
password: string;
};
export default class extends React.Component<LoginFormProps, LoginFormState> {
state = {
username: '',
email: '',
password: ''
};
......@@ -95,22 +95,20 @@ export default class extends React.Component<LoginFormProps, LoginFormState> {
<Row>
<Col>
<TextField>
<Label>Username:</Label>
<Label>Email address:</Label>
<TextInput
placeholder="Enter your username"
value={this.state.username}
validation={this.getValidation(ValidationField.username)}
placeholder="Enter your email address"
value={this.state.email}
validation={this.getValidation(ValidationField.email)}
onChange={(evt: any) => {
this.setState({
username: evt.target.value
email: evt.target.value
});
onInputChange(ValidationField.username, evt.target.value);
onInputChange(ValidationField.email, evt.target.value);
}}
/>
<Message
validation={this.getValidation(ValidationField.username)}
>
{this.getValidationMessage(ValidationField.username)}
<Message validation={this.getValidation(ValidationField.email)}>
{this.getValidationMessage(ValidationField.email)}
</Message>
</TextField>
<Spacer />
......
......@@ -6,7 +6,7 @@ export enum ValidationType {
}
export enum ValidationField {
username,
email,
password
}
......
......@@ -31,7 +31,7 @@ const Sidebar = styled.div`
const stepScrollTo = {
1: 0,
2: 650
2: 450
};
//TODO this should be offloaded to an API
......@@ -91,22 +91,30 @@ const Step2Section = styled.div<any>`
transition: opacity 1.75s linear;
`;
const TagsNoneSelected = ({ what }) => {
return (
<div style={{ paddingTop: '8px', color: 'grey' }}>No {what} selected</div>
);
};
const Interests = ({ active, interests, onTagClick }) => (
<Step2Section active={active}>
<H4>Interests</H4>
<TagContainer>
{interests.length
? interests.map(interest => (
<Tag
focused
closeable
key={interest}
onClick={() => onTagClick(interest)}
>
{interest}
</Tag>
))
: 'None selected'}
{interests.length ? (
interests.map(interest => (
<Tag
focused
closeable
key={interest}
onClick={() => onTagClick(interest)}
>
{interest}
</Tag>
))
) : (
<TagsNoneSelected what="interests" />
)}
</TagContainer>
<Button onClick={() => alert('add interest clicked')}>Add interest</Button>
</Step2Section>
......@@ -116,18 +124,20 @@ const Languages = ({ active, languages }) => (
<Step2Section active={active}>
<H4>Languages</H4>
<TagContainer>
{languages.length
? languages.map(lang => (
<Tag
focused
closeable
key={lang}
onClick={() => alert('lang clicked')}
>
{lang}
</Tag>
))
: 'None selected'}
{languages.length ? (
languages.map(lang => (
<Tag
focused
closeable
key={lang}
onClick={() => alert('lang clicked')}
>
{lang}
</Tag>
))
) : (
<TagsNoneSelected what="languages" />
)}
</TagContainer>
<Button onClick={() => alert('add lang clicked')}>Add language</Button>
</Step2Section>
......@@ -136,13 +146,16 @@ const Languages = ({ active, languages }) => (
export default class SignUp extends React.Component<SignUpProps, SignUpState> {
static stepComponents = [Step1, Step2];
// container of the user profile, ref. is used
// to scroll container on sign up step change
_profileElem: HTMLElement;
state: SignUpState = {
currentStep: -1,
user: {
username: '',
name: '',
email: '',
bio: '',
emojiId: generateEmojiId(),
avatarImage: undefined,
profileImage: undefined,
......@@ -159,7 +172,7 @@ export default class SignUp extends React.Component<SignUpProps, SignUpState> {
this.state.currentStep = Number(props.match.params.step);
if (!this.state.user.username && this.state.currentStep > 1) {
if (!this.state.user.name && this.state.currentStep > 1) {
this.state.redirect = '/sign-up/1';
return;
}
......@@ -351,7 +364,7 @@ export default class SignUp extends React.Component<SignUpProps, SignUpState> {
</Row>
{this.getStepComponent()}
<Row style={{ flexGrow: 1 }} />
<Row>
<Row style={{ minHeight: '42px', marginTop: '10px' }}>
{this.getNextStepName() ? (
<Col
style={{
......@@ -384,15 +397,15 @@ export default class SignUp extends React.Component<SignUpProps, SignUpState> {
body={({ containerProps }) => {
return (
<SignUpProfileSection {...containerProps}>
<Languages
active={this.state.currentStep > 1}
languages={this.state.user.languages}
/>
<Interests
onTagClick={interest => this.toggleUserInterest(interest)}
active={this.state.currentStep > 1}
interests={this.state.user.interests}
/>
<Languages
active={this.state.currentStep > 1}
languages={this.state.user.languages}
/>
</SignUpProfileSection>
);
}}
......
......@@ -5,6 +5,7 @@ import { Col, Row } from '@zendeskgarden/react-grid';
import H6 from '../../components/typography/H6/H6';
import P from '../../components/typography/P/P';
import TextInput from '../../components/inputs/Text/Text';
import TextArea from '../../components/inputs/TextArea/Textarea';
import Button from '../../components/elements/Button/Button';
import LanguageSelect from '../../components/inputs/LanguageSelect/LanguageSelect';
import styled from '../../themes/styled';
......@@ -32,11 +33,11 @@ export default ({ user, randomizeEmojiId, linkUserState }) => {
details below to build it.
</P>
<TextField>
<Label>Username</Label>
<Label>Name</Label>
<TextInput
value={user.username}
onChange={linkUserState('username')}
placeholder="e.g. joebloggs84"
value={user.name}
onChange={linkUserState('name')}
placeholder="e.g. Moodler Joe"
maxLength={20}
/>
</TextField>
......@@ -66,11 +67,21 @@ export default ({ user, randomizeEmojiId, linkUserState }) => {
<TextInput
value={user.email}
onChange={linkUserState('email')}
placeholder="e.g. joebloggs@example.com"
placeholder="e.g. joe@moodle.net"
maxLength={100}
/>
</TextField>
<Spacer />
<TextField>
<Label>Bio</Label>
<TextArea
value={user.bio}
onChange={linkUserState('bio')}
placeholder="Tell us a bit about yourself"
maxLength={250}
/>
</TextField>
<Spacer />
<TextField>
<Label>Language</Label>
<LanguageSelect fullWidth={true} />
......
......@@ -10,14 +10,18 @@ import styled from '../../themes/styled';
import User from '../../types/User';
//TODO get tags from the API
const words = `offer,segment,slave,duck,instant,market,degree,populate,chick,dear,enemy,reply,drink,occur,support,shell,neck`.split(
','
);
const words = `Applied Sciences, K12, Performing Arts, Humanities, Higher Education, Social Sciences, Vocational Education, Professional Education, Formal Sciences, Natural Sciences, Visual Arts`
.split(',')
.map(s => s.trim());
const InterestsSearchResultsContainer = styled.div`
margin: 20px 0 0 0;
`;
const OverflowCol = styled(Col)`
overflow: auto;
`;
function InterestsSearchResults({ status, count, result, children }) {
if (status === SearchStatus.complete) {
return (
......@@ -115,7 +119,7 @@ export default class extends React.Component<Step2Props, Step2State> {
return (
<>
<Row>
<Col>
<OverflowCol>
<H6 style={{ borderBottom: '1px solid lightgrey' }}>
<span style={{ color: 'darkgrey', fontSize: '.7em' }}>2.</span>{' '}
Your Interests
......@@ -156,7 +160,7 @@ export default class extends React.Component<Step2Props, Step2State> {
</Tag>
))}
</TagContainer>
</Col>
</OverflowCol>
</Row>
</>
);
......
......@@ -189,10 +189,7 @@ export default function(props: UserProfileProps) {
<UserDetails>
<H6>{props.user.emojiId}</H6>
<H6>
<FadedFallbackText
value={props.user.username}
fallback="joebloggs84"
/>
<FadedFallbackText value={props.user.name} fallback="Moodler Joe" />
</H6>
<H6>
<FadedFallbackText value={props.user.role} fallback="Head Teacher" />
......
export default interface User {
username: string;
name: string;
email: string;
bio: string;
emojiId: string;
avatarImage?: string;
profileImage?: string;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment