feat: add AutoComplete component
This commit is contained in:
235
src/common/components/AutoComplete/index.js
Normal file
235
src/common/components/AutoComplete/index.js
Normal 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);
|
||||
@@ -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';
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user