Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 56 additions & 15 deletions src/pages/AddProject.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,25 @@ import "../style/pages/AddProject.css";
import classNames from "classnames/bind"
import axios from "axios";
import { AppContext } from "../contexts/AppContext";
import CreatableSelect from 'react-select/creatable';
import { withRouter, RouteComponentProps } from 'react-router-dom';
import Cookies from 'js-cookie';
import Modal from 'react-modal';
import CreatableSelect from 'react-select/creatable';

const validGitHubRepo = /^(?:https:\/\/)*github[.]com\/([a-z0-9-]+)\/([a-z0-9\-_]+)\/?$/;

type FormOption = {
value: string,
label: string
}

type FormOptions = Array<FormOption>;

type FormState = {
experienceLevel: string,
currentLeadPosition: string,
githubRepo: string,
lookingFor: string,
lookingFor: FormOptions,
techStack: { value: string, label: string }[],
errors: {
experienceLevel: string,
Expand Down Expand Up @@ -42,7 +49,7 @@ const validateForm = (state) => {
let hasInput = false;

let inputFields = Object.values(state).filter(
(value: any) => value.length === 0);
(value: any) => value === null || value.length === 0);

hasInput = (inputFields.length === 0) ? true : false;

Expand All @@ -60,7 +67,7 @@ class AddProject extends React.Component<RouteComponentProps, FormState> {
experienceLevel: "",
currentLeadPosition: "",
githubRepo: "",
lookingFor: "",
lookingFor: [],
techStack: [],
errors: {
experienceLevel: "",
Expand All @@ -75,6 +82,26 @@ class AddProject extends React.Component<RouteComponentProps, FormState> {
cancelModalOpen: false
}

// TODO: These values will be coming in from a getPosition API when #114 is implemented.
lookingForOptions: FormOptions = [
{
value: 'Frontend Engineer',
label: 'Frontend Engineer'
},
{
value: 'Backend Engineer',
label: 'Backend Engineer'
},
{
value: 'Product Manager',
label: 'Product Manager'
},
{
value: 'UX Researcher',
label: 'UX Researcher'
}
];

csrf = '';

isPublicGithubRepo = (githubUrl) => {
Expand Down Expand Up @@ -119,11 +146,6 @@ class AddProject extends React.Component<RouteComponentProps, FormState> {
}
break;

case 'lookingFor':
errors.lookingFor =
value.length === 0 ? "Field cannot be empty" : "";
break;

case 'techStack':
errors.techStack =
value.length === 0 ? "Tech stack cannot be empty" : "";
Expand All @@ -140,6 +162,23 @@ class AddProject extends React.Component<RouteComponentProps, FormState> {
} as Pick<FormState, keyof FormState>)
}

handleCreatableChange = (value: FormOptions, actionMeta: any) => {
const name = actionMeta.name;
const errors = this.state.errors;

switch (name) {
case 'lookingFor':
errors.lookingFor =
!value || value.length === 0 ? "Field cannot be empty" : "";
break;
}

this.setState({
[name]: value,
errors
} as Pick<FormState, keyof FormState>);
}

showErrors = () => {
let currErrors = this.state.errors;
if (!!!this.state.experienceLevel) {
Expand Down Expand Up @@ -181,7 +220,7 @@ class AddProject extends React.Component<RouteComponentProps, FormState> {
const data = {
experience_lvl: stateDict.experienceLevel,
github_url: stateDict.githubRepo,
looking_for: stateDict.lookingFor,
looking_for: stateDict.lookingFor.map(option => option.label).join(', '),
position: stateDict.currentLeadPosition,
csrfmiddlewaretoken: this.csrf
}
Expand Down Expand Up @@ -350,14 +389,16 @@ class AddProject extends React.Component<RouteComponentProps, FormState> {
Select or enter what type of contributors you're looking for
</label>
{/* TODO: Add fixed values for cols, rows */}
<textarea
<CreatableSelect
id="looking-for"
name="lookingFor"
value={this.state.lookingFor}
onChange={this.handleChange}
onBlur={this.handleChange}
style={{ "resize": "none" }}
className={classNames({ "field-error": errors.lookingFor.length > 0 })}
onChange={this.handleCreatableChange}
options={this.lookingForOptions}
placeholder="Select or enter contributor type"
isMulti
className={classNames('creatable', { "creatable-error": errors.lookingFor.length > 0 })}
classNamePrefix="creatable"
/>
{errors.lookingFor.length > 0 && <span className="error">{errors.lookingFor}</span>}

Expand Down
20 changes: 20 additions & 0 deletions src/style/pages/AddProject.css
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,19 @@ textarea {
margin-bottom: 36px;
}

.creatable {
margin-bottom: 36px;
}
.creatable input,
.creatable .creatable__multi-value__label {
font-size: 16px !important;
padding: 10px !important;
margin-bottom: 0;
}
.creatable .creatable__control {
border-radius: 0px;
}

span {
margin-top: -24px;
padding-bottom: 24px;
Expand All @@ -68,6 +81,13 @@ span {
outline-color: #f00;
}

.creatable-error .creatable__control {
border: 1px solid #c23b22;
}
.creatable-error .creatable__control:focus {
outline-color: #f00;
}

.error {
color: #c23b22;
}
Expand Down