feat: add AutoComplete component

This commit is contained in:
2019-01-29 12:46:49 +07:00
parent 3ee2588d4e
commit dfa4df84bf
6 changed files with 563 additions and 103 deletions

View File

@@ -0,0 +1,235 @@
/* eslint-disable react/prop-types, react/jsx-handler-names */
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import Select from 'react-select';
import { withStyles } from '@material-ui/core/styles';
import Typography from '@material-ui/core/Typography';
import NoSsr from '@material-ui/core/NoSsr';
import TextField from '@material-ui/core/TextField';
import Paper from '@material-ui/core/Paper';
import Chip from '@material-ui/core/Chip';
import MenuItem from '@material-ui/core/MenuItem';
import CancelIcon from '@material-ui/icons/Cancel';
import { emphasize } from '@material-ui/core/styles/colorManipulator';
const styles = theme => ({
root: {
flexGrow: 1,
// height: 250,
},
input: {
display: 'flex',
padding: 0,
},
valueContainer: {
display: 'flex',
flexWrap: 'wrap',
flex: 1,
alignItems: 'center',
overflow: 'hidden',
},
chip: {
margin: `${theme.spacing.unit / 2}px ${theme.spacing.unit / 4}px`,
},
chipFocused: {
backgroundColor: emphasize(
theme.palette.type === 'light' ? theme.palette.grey[300] : theme.palette.grey[700],
0.08,
),
},
noOptionsMessage: {
padding: `${theme.spacing.unit}px ${theme.spacing.unit * 2}px`,
},
singleValue: {
fontSize: 16,
},
placeholder: {
position: 'absolute',
left: 2,
fontSize: 16,
},
paper: {
position: 'absolute',
zIndex: 1,
marginTop: theme.spacing.unit,
left: 0,
right: 0,
},
divider: {
height: theme.spacing.unit * 2,
},
});
function NoOptionsMessage(props) {
return (
<Typography
color="textSecondary"
className={props.selectProps.classes.noOptionsMessage}
{...props.innerProps}
>
{props.children}
</Typography>
);
}
function inputComponent({ inputRef, ...props }) {
return <div ref={inputRef} {...props} />;
}
function Control(props) {
return (
<TextField
margin="normal"
variant="outlined"
fullWidth
style={{padding: 5}}
InputProps={{
inputComponent,
inputProps: {
className: props.selectProps.classes.input,
inputRef: props.innerRef,
children: props.children,
...props.innerProps,
},
}}
{...props.selectProps.textFieldProps}
/>
);
}
function Option(props) {
return (
<MenuItem
buttonRef={props.innerRef}
selected={props.isFocused}
component="div"
style={{
fontWeight: props.isSelected ? 500 : 400,
}}
{...props.innerProps}
>
{props.children}
</MenuItem>
);
}
function Placeholder(props) {
return (
<Typography
color="textSecondary"
className={props.selectProps.classes.placeholder}
{...props.innerProps}
>
{props.children}
</Typography>
);
}
function SingleValue(props) {
return (
<Typography className={props.selectProps.classes.singleValue} {...props.innerProps}>
{props.children}
</Typography>
);
}
function ValueContainer(props) {
return <div className={props.selectProps.classes.valueContainer}>{props.children}</div>;
}
function MultiValue(props) {
return (
<Chip
tabIndex={-1}
label={props.children}
className={classNames(props.selectProps.classes.chip, {
[props.selectProps.classes.chipFocused]: props.isFocused,
})}
onDelete={props.removeProps.onClick}
deleteIcon={<CancelIcon {...props.removeProps} />}
/>
);
}
function Menu(props) {
return (
<Paper square className={props.selectProps.classes.paper} {...props.innerProps}>
{props.children}
</Paper>
);
}
const components = {
Control,
Menu,
MultiValue,
NoOptionsMessage,
Option,
Placeholder,
SingleValue,
ValueContainer,
};
class IntegrationReactSelect extends React.Component {
state = {
single: null,
multi: null,
};
handleChange = name => value => {
const {onChange=()=>{}} = this.props;
onChange(value);
this.setState({
[name]: value,
});
};
render() {
const { classes, theme } = this.props;
const selectStyles = {
input: base => ({
...base,
color: theme.palette.text.primary,
'& input': {
font: 'inherit',
// padding: '15px'
},
padding: '15px'
}),
};
return (
<div className={classes.root} style={{
// backgroundColor: "red",
}}>
<NoSsr>
<Select
classes={classes}
styles={selectStyles}
options={this.props.suggestions}
components={components}
value={this.state.single}
onChange={this.handleChange('single')}
placeholder={this.props.placeholder || "Please select data"}
/>
</NoSsr>
</div>
);
}
}
IntegrationReactSelect.propTypes = {
classes: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired,
suggestions: PropTypes.array.isRequired,
placeholder: PropTypes.string,
onChange: PropTypes.func
};
export default withStyles(styles, { withTheme: true })(IntegrationReactSelect);

View File

@@ -30,7 +30,7 @@ imageUrl = "https://giift-api.asacreative.com";
type = 'localhost';
if(window.location.href.includes("localhost") || window.location.href.includes("marketplace-store")){
// appUrl = 'http://localhost:7700';
// apiUrl = "http://localhost:4001/"
apiUrl = "http://localhost:4001/"
}else{
appUrl = 'https://sillyfish.asacreative.com';
}

View File

@@ -20,19 +20,29 @@ import schema from 'async-validator'
import { startCase } from 'lodash';
import { Upload, Icon, message } from 'antd';
import AutoComplete from './../../components/AutoComplete';
// const province = require("./../../../../assets/data/province.json");
// const city = require("./../../../../assets/data/city.json");
// const district = require("./../../../../assets/data/district.json");
// const subdistrict = require("./../../../../assets/data/subdistrict.json");
@inject('appstate')
@observer
class RegisterPage extends React.Component {
state = {
showPassword: false,
showConfirmPassword: false,
openDialog: false,
isLoading: false,
// form
phone_number: "",
email: "",
password: "",
confirmPassword: "",
full_name: "",
showPassword: false,
showConfirmPassword: false,
openDialog: false,
isLoading: false,
no_ktp: '',
upload_ktp: '',
upload_photo: '',
@@ -42,13 +52,16 @@ class RegisterPage extends React.Component {
district: '',
sub_district: '',
zip_code: '',
};
constructor(props) {
super(props);
this.authStore = props.appstate.auth;
// this.global_ui = props.store.global_ui;
this.http = props.appstate.http;
}
componentDidMount() {
}
handleChange = name => event => {
@@ -76,50 +89,14 @@ class RegisterPage extends React.Component {
email: this.state.email,
phone_number: this.state.phone_number,
password: this.state.password
}
};
this.authStore.register(data).then(res => {
setTimeout(() => {
this.setState({ isLoading: false });
}, 1000);
}).catch(err => {
this.setState({ isLoading: false });
})
// let rules = {
// full_name : {
// type : 'string',
// required : true,
// min : 3
// },
// phone_number : {
// type : 'string',
// required : true,
// min : 8
// },
// email : {
// type : 'email',
// required : true
// }
// };
// const validator = new schema(rules);
// validator.validate(this.state, (errors, fields) => {
// if(errors) {
// this.global_ui.openAlert({
// type : 'error',
// title : startCase(errors[0].message),
// subtitle : 'Please validate the input'
// });
// return false;
// }
// this.global_ui.openLoader();
// setTimeout(()=>{
// this.global_ui.closeLoader();
// this.global_ui.openAlert({
// title : "Registration Succeed",
// subtitle : 'Thank you for register and enjoy your day',
// type : 'success'
// });
// },1000)
// });
});
};
handleChangeUploadKtp = (info) => {
@@ -134,7 +111,7 @@ class RegisterPage extends React.Component {
loading: false,
}));
}
}
};
handleChangeUploadPhoto = (info) => {
if (info.file.status === 'uploading') {
@@ -148,33 +125,37 @@ class RegisterPage extends React.Component {
loading: false,
}));
}
}
};
render() {
const { classes } = this.props;
const uploadButtonKtp = (
<div>
<Icon type={this.state.loading ? 'loading' : 'plus'} />
<div className="ant-upload-text">Upload KTP</div>
</div>
);
const uploadButtonPhoto = (
<div>
<Icon type={this.state.loading ? 'loading' : 'plus'} />
<div className="ant-upload-text">Upload Photo</div>
</div>
);
const upload_ktp = this.state.upload_ktp;
const upload_photo = this.state.upload_photo;
return (
<div className={classes.container}>
{/*<AlertSuccess open={appStore.global_ui.openSuccess} onClose={()=>appStore.global_ui.closeAlertSuccess()}/>*/}
<Grid container spacing={0} className={classes.gridContainer}>
<Grid item xs={12} className={classes.logoContainer}>
<Grid item xs={16} className={classes.logoContainer}>
<img src={require('../../../../assets/images/logo_new.png')} className={classes.logo} />
</Grid>
<Grid item xs={12} sm={12} md={10} lg={10} className={classes.registerContainer}>
<Grid item xs={16} sm={16} md={10} lg={10} className={classes.registerContainer}>
<Grid container spacing={24} className={classes.registerPaper}>
<Hidden smDown>
<Grid item xs={5}>
@@ -187,7 +168,7 @@ class RegisterPage extends React.Component {
</Typography>
</Grid>
</Hidden>
<Grid item xs={12} sm={12} md={7} style={{ paddingLeft: 50, paddingRight: 50 }}>
<Grid item xs={16} sm={16} md={7} style={{ paddingLeft: 50, paddingRight: 50 }}>
<Paper className={classes.formRegister}>
<Typography variant="h6" gutterBottom>
Register Now
@@ -199,8 +180,8 @@ class RegisterPage extends React.Component {
display: 'flex',
flexDirection: 'row'
}}>
<Grid container spacing={12}>
<Grid item xs={12} sm={12} md={6} style={{ paddingLeft: 5, paddingRight: 5 }}>
<Grid container spacing={16}>
<Grid item xs={16} sm={16} md={6} style={{ paddingLeft: 5, paddingRight: 5 }}>
<TextField
id="name"
label="Full name"
@@ -212,7 +193,7 @@ class RegisterPage extends React.Component {
fullWidth
/>
</Grid>
<Grid item xs={12} sm={12} md={6} style={{ paddingLeft: 5, paddingRight: 5 }}>
<Grid item xs={16} sm={16} md={6} style={{ paddingLeft: 5, paddingRight: 5 }}>
<TextField
id="phone"
label="Phone Number"
@@ -225,7 +206,7 @@ class RegisterPage extends React.Component {
/>
</Grid>
<Grid item xs={12} sm={12} md={6} style={{ paddingLeft: 5, paddingRight: 5 }}>
<Grid item xs={16} sm={16} md={6} style={{ paddingLeft: 5, paddingRight: 5 }}>
<TextField
id="email"
label="Email"
@@ -236,7 +217,7 @@ class RegisterPage extends React.Component {
fullWidth
/>
</Grid>
<Grid item xs={12} sm={12} md={6} style={{ paddingLeft: 5, paddingRight: 5 }}>
<Grid item xs={16} sm={16} md={6} style={{ paddingLeft: 5, paddingRight: 5 }}>
<TextField
id="ktp"
label="Nomor KTP"
@@ -249,7 +230,7 @@ class RegisterPage extends React.Component {
/>
</Grid>
<Grid item xs={12} sm={12} md={6} style={{ paddingLeft: 5, paddingRight: 5,paddingTop:16 }}>
<Grid item xs={16} sm={16} md={6} style={{ paddingLeft: 5, paddingRight: 5,paddingTop:16 }}>
<Upload
name="avatar"
listType="picture-card"
@@ -261,7 +242,7 @@ class RegisterPage extends React.Component {
{upload_ktp ? <img src={upload_ktp} alt="avatar" /> : uploadButtonKtp}
</Upload>
</Grid>
<Grid item xs={12} sm={12} md={6} style={{ paddingLeft: 5, paddingRight: 5, paddingTop:16 }}>
<Grid item xs={16} sm={16} md={6} style={{ paddingLeft: 5, paddingRight: 5, paddingTop:16 }}>
<Upload
style={{ marginTop: 16, marginBottom: 8 }}
name="avatar"
@@ -275,7 +256,7 @@ class RegisterPage extends React.Component {
</Upload>
</Grid>
<Grid item xs={12} sm={12} md={6} style={{ paddingLeft: 5, paddingRight: 5 }}>
<Grid item xs={16} sm={16} md={6} style={{ paddingLeft: 5, paddingRight: 5 }}>
<TextField
id="address"
label="Address"
@@ -286,53 +267,90 @@ class RegisterPage extends React.Component {
fullWidth
/>
</Grid>
<Grid item xs={12} sm={12} md={6} style={{ paddingLeft: 5, paddingRight: 5 }}>
<TextField
id="province"
label="Province"
value={this.state.province}
onChange={this.handleChange('province')}
margin="normal"
variant="outlined"
fullWidth
/>
<Grid item xs={16} sm={16} md={6} style={{ paddingLeft: 5, paddingRight: 5 }}>
{/*<TextField*/}
{/*id="province"*/}
{/*label="Province"*/}
{/*value={this.state.province}*/}
{/*onChange={this.handleChange('province')}*/}
{/*margin="normal"*/}
{/*variant="outlined"*/}
{/*fullWidth*/}
{/*/>*/}
<AutoComplete
placeholder={"Province"}
onChange={val => console.log(val)}
suggestions={[
{
label: "Indonesia",
value: "ID"
}
]}/>
</Grid>
<Grid item xs={12} sm={12} md={6} style={{ paddingLeft: 5, paddingRight: 5 }}>
<TextField
id="city"
label="City"
value={this.state.city}
onChange={this.handleChange('city')}
margin="normal"
variant="outlined"
fullWidth
/>
<Grid item xs={16} sm={16} md={6} style={{ paddingLeft: 5, paddingRight: 5 }}>
{/*<TextField*/}
{/*id="city"*/}
{/*label="City"*/}
{/*value={this.state.city}*/}
{/*onChange={this.handleChange('city')}*/}
{/*margin="normal"*/}
{/*variant="outlined"*/}
{/*fullWidth*/}
{/*/>*/}
<AutoComplete
placeholder={"City"}
onChange={val => console.log(val)}
suggestions={[
{
label: "Indonesia",
value: "ID"
}
]}/>
</Grid>
<Grid item xs={12} sm={12} md={6} style={{ paddingLeft: 5, paddingRight: 5 }}>
<TextField
id="district"
label="District"
value={this.state.district}
onChange={this.handleChange('district')}
margin="normal"
variant="outlined"
fullWidth
/>
<Grid item xs={16} sm={16} md={6} style={{ paddingLeft: 5, paddingRight: 5 }}>
{/*<TextField*/}
{/*id="district"*/}
{/*label="District"*/}
{/*value={this.state.district}*/}
{/*onChange={this.handleChange('district')}*/}
{/*margin="normal"*/}
{/*variant="outlined"*/}
{/*fullWidth*/}
{/*/>*/}
<AutoComplete
placeholder={"District"}
onChange={val => console.log(val)}
suggestions={[
{
label: "Indonesia",
value: "ID"
}
]}/>
</Grid>
<Grid item xs={12} sm={12} md={6} style={{ paddingLeft: 5, paddingRight: 5 }}>
<TextField
id="sub_district"
label="Sub district"
value={this.state.sub_district}
onChange={this.handleChange('sub_district')}
margin="normal"
variant="outlined"
fullWidth
/>
<Grid item xs={16} sm={16} md={6} style={{ paddingLeft: 5, paddingRight: 5 }}>
{/*<TextField*/}
{/*id="sub_district"*/}
{/*label="Sub district"*/}
{/*value={this.state.sub_district}*/}
{/*onChange={this.handleChange('sub_district')}*/}
{/*margin="normal"*/}
{/*variant="outlined"*/}
{/*fullWidth*/}
{/*/>*/}
<AutoComplete
placeholder={"Subdistrict"}
onChange={val => console.log(val)}
suggestions={[
{
label: "Indonesia",
value: "ID"
}
]}/>
</Grid>
<Grid item xs={12} sm={12} md={6} style={{ paddingLeft: 5, paddingRight: 5 }}>
<Grid item xs={16} sm={16} md={6} style={{ paddingLeft: 5, paddingRight: 5 }}>
<TextField
id="zip_code"
label="Zip Code"
@@ -344,7 +362,7 @@ class RegisterPage extends React.Component {
/>
</Grid>
<Grid item xs={12} sm={12} md={6} style={{ paddingLeft: 5, paddingRight: 5 }}>
<Grid item xs={16} sm={16} md={6} style={{ paddingLeft: 5, paddingRight: 5 }}>
<TextField
id="password"
label="Password"
@@ -368,7 +386,7 @@ class RegisterPage extends React.Component {
}}
/>
</Grid>
<Grid item xs={12} sm={12} md={6} style={{ paddingLeft: 5, paddingRight: 5 }}>
<Grid item xs={16} sm={16} md={6} style={{ paddingLeft: 5, paddingRight: 5 }}>
<TextField
id="confirmPassword"
label="Re-type Password"
@@ -411,4 +429,4 @@ class RegisterPage extends React.Component {
}
}
export default withStyles(styles)(RegisterPage);
export default withStyles(styles)(RegisterPage);