Initial commit

This commit is contained in:
Rifqy Zacky Ariadhy
2019-01-02 18:39:53 +07:00
commit 1a000700e6
781 changed files with 95892 additions and 0 deletions

View File

@@ -0,0 +1,294 @@
import React from 'react';
import {inject, observer} from 'mobx-react';
import {DatePicker, MenuItem, SelectField, TextField, Checkbox,
AutoComplete, } from 'material-ui';
import { Upload, Icon, Modal, Input, Select, Switch, message, Button as ButtonAntd,Popover } from 'antd';
import schema from 'async-validator'
import startCase from 'lodash.startcase';
import moment from 'moment';
import get from 'lodash.get';
import NumberFormat from 'react-number-format';
import {featherIconLists} from "./icons";
// as MCIcons from 'react-native-vector-icons/glyphmaps/MaterialCommunityIcons.json';
import FeatherIcon from 'feather-icons-react';
const InputGroup = Input.Group;
const { TextArea } = Input;
@inject('appstate')
@observer
export default class CategoryData extends React.Component {
constructor(props) {
super(props);
this.props = props;
this.state = {
dataSource: [],
formData: Object.assign({
name : '',
url : '',
icon : '',
type : 'url'
},props.defaultValue ) || {},
checked: true,
errorText: {},
icon_search : '',
tag_search : '',
onChangeTimeoutId: false,
};
this.http = props.appstate.http;
this.customMenu = props.appstate.custom_menu;
this.tags = props.appstate.tags;
}
// componentWillUnmount(){
// }
async componentDidMount() {
const {defaultValue={},mode} = this.props;
await this.tags.getAll();
this.setState({
formData : Object.assign(defaultValue,this.state.formData,
{
tag : get(defaultValue,'additional_data.tag_id',false) ? defaultValue.additional_data.tag_id : null,
post_template : get(defaultValue,'additional_data.template',false) ? defaultValue.additional_data.template : null
}),
icon_search : defaultValue.icon,
tag_search : get(defaultValue,'additional_data.tag_id',false) ? this.tags.data.find(it=>it.id === defaultValue.additional_data.tag_id).name : ""
},()=>this.triggerOnChange(2));
let icons = [];
featherIconLists.map(it=>{
let _name = it;
let _val = <MenuItem primaryText={_name} leftIcon={ <FeatherIcon icon={it} size="48"/>}/>
icons.push({text:_name, value:(_val), valueKey:it});
});
this.setState({
dataSource : icons
})
}
triggerOnChange(key) {
this.props.onChangeData(this.state.formData);
}
updateCheck() {
this.setState((oldState) => {
return {
checked: !oldState.checked,
};
});
}
render() {
const wrapperText = key => ele => React.cloneElement(ele, {
value: this.state.formData[key],
errorText: this.state.errorText[key],
onChange: (e) => {
this.setState({
formData: {
...this.state.formData,
[key]: e.target.value,
}
}, () => this.triggerOnChange(key));
}
});
const wrapperSelect = key => ele => React.cloneElement(ele, {
value: this.state.formData[key],
errorText: this.state.errorText[key],
onChange: (e, k, v) => {
this.setState({
formData: {
...this.state.formData,
[key]: v,
}
}, () => this.triggerOnChange(key));
}
});
const wrapperSwitch = key => ele => React.cloneElement(ele, {
checked: this.state.formData[key],
errorText: this.state.errorText[key],
onCheck: (e, v) => {
this.setState({
formData: {
...this.state.formData,
[key]: v,
}
}, () => this.triggerOnChange(key));
}
});
const wrapperAutocomplete = key => ele => React.cloneElement(ele, {
value : this.state.formData[key],
searchText : this.state[`${key}_search`],
onNewRequest: (v) => {
this.setState({
formData: {
...this.state.formData,
[key]: (key == 'tag') ? v.id : v.valueKey,
}
}, () => this.triggerOnChange(key));
}
});
const {mode="create"} = this.props;
let popoverText = (
<div>
<p>We used <strong>material design icon</strong> for our icon.<br/>To view list of icon please visit <a href="https://materialdesignicons.com" target="_blank">https://materialdesignicons.com/</a> then search and select an icon you desire</p>
</div>
)
return(
<div style={{marginTop: 10}}>
<div className={"row"}>
<div className={"col s12"}>
<div>
<p className="label-form">Type</p>
{wrapperSelect("type")(
<SelectField>
<MenuItem value={'url'} primaryText="Url" />
<MenuItem value={'post'} primaryText="Post" />
</SelectField>
)}
</div>
</div>
</div>
<div className={"row"}>
<div className={"col s12"}>
<div>
<p className="label-form">Name</p>
{wrapperText("name")(
<TextField
hintText="E.g. Homepage"
fullWidth={true}
/>
)}
</div>
</div>
</div>
{
(this.state.formData.type == 'url') && <div className={"row"}>
<div className={"col s12"}>
<div>
<p className="label-form">URL</p>
{wrapperText("url")(
<TextField
hintText="E.g. https://www.yournicewebsite.com"
fullWidth={true}
/>
)}
</div>
</div>
</div>
}
{
(this.state.formData.type == 'post') &&
<div>
<div className={"row"}>
<div className={"col s6"}>
<div>
<p className="label-form">Post Category</p>
{/*{wrapperAutocomplete("tag")(*/}
{/*<AutoComplete*/}
{/*hintText="E.g. Face, People"*/}
{/*dataSource={this.tags.data}*/}
{/*filter={AutoComplete.fuzzyFilter}*/}
{/*dataSourceConfig={{text : 'name',value:'id'}}*/}
{/*onUpdateInput={(val)=>this.setState({tag_search :val})}*/}
{/*maxSearchResults={5}*/}
{/*openOnFocus={true}*/}
{/*fullWidth={true}*/}
{/*/>*/}
{/*)}*/}
{wrapperSelect("tag")(
<SelectField>
{
this.tags.data.map(it=>(
<MenuItem value={it.id} primaryText={it.name}/>
))
}
</SelectField>
)}
</div>
</div>
<div className={"col s6"}>
<div>
<p className="label-form">Post Template</p>
{wrapperSelect("post_template")(
<SelectField>
<MenuItem value={'template1'} primaryText="Template Full Card" />
<MenuItem value={'template2'} primaryText="Template Standart List" />
</SelectField>
)}
</div>
</div>
</div>
</div>
}
<div className={"row"}>
<div className={"col s6"}>
<div>
<p className="label-form">Icon <Popover content={popoverText} title="Icons"><Icon type="info-circle"/></Popover></p>
{wrapperAutocomplete("icon")(
<AutoComplete
hintText="E.g. Face, People"
dataSource={this.state.dataSource}
// filter={(searchText,key)=>{
// console.log(searchText,typeof searchText, key, typeof key);
// return true;
// }}
filter={AutoComplete.caseInsensitiveFilter}
dataSourceConfig={{text : 'text',value:'valueKey'}}
onUpdateInput={(val)=>this.setState({icon_search :val})}
maxSearchResults={20}
listStyle={{ maxHeight: 200, overflow: 'auto' }}
openOnFocus={true}
fullWidth={true}
/>
)}
</div>
</div>
<div className={"col s6"}>
{
// (this.state.formData.icon !== '') && <i className={`mdi mdi-${this.state.formData.icon}`} style={{fontSize:'50pt'}}></i>
(this.state.formData.icon !== '') && <FeatherIcon icon={this.state.formData.icon} size="48"/>
}
</div>
</div>
<div className={"row"}>
<div className={"col s6"}>
<div>
<p className="label-form">Order</p>
{wrapperText("order")(
<TextField
hintText="Custom menu appearance order"
type={"number"}
fullWidth={true}
/>
)}`
</div>
</div>
</div>
</div>
);
}
}

View File

@@ -0,0 +1,3 @@
export const featherIconLists = [
"activity","airplay","alert-circle","alert-octagon","alert-triangle","align-center","align-justify","align-left","align-right","anchor","aperture","archive","arrow-down","arrow-down-circle","arrow-down-left","arrow-down-right","arrow-left","arrow-left-circle","arrow-right","arrow-right-circle","arrow-up","arrow-up-circle","arrow-up-left","arrow-up-right","at-sign","award","bar-chart","bar-chart-2","battery","battery-charging","bell","bell-off","bluetooth","bold","book","book-open","bookmark","box","briefcase","calendar","camera","camera-off","cast","check","check-circle","check-square","chevron-down","chevron-left","chevron-right","chevron-up","chevrons-down","chevrons-left","chevrons-right","chevrons-up","chrome","circle","clipboard","clock","cloud","cloud-drizzle","cloud-lightning","cloud-off","cloud-rain","cloud-snow","code","codepen","command","compass","copy","corner-down-left","corner-down-right","corner-left-down","corner-left-up","corner-right-down","corner-right-up","corner-up-left","corner-up-right","cpu","credit-card","crop","crosshair","database","delete","disc","dollar-sign","download","download-cloud","droplet","edit","edit-2","edit-3","external-link","eye","eye-off","facebook","fast-forward","feather","file","file-minus","file-plus","file-text","film","filter","flag","folder","folder-minus","folder-plus","gift","git-branch","git-commit","git-merge","git-pull-request","github","gitlab","globe","grid","hard-drive","hash","headphones","heart","help-circle","home","image","inbox","info","instagram","italic","layers","layout","life-buoy","link","link-2","linkedin","list","loader","lock","log-in","log-out","mail","map","map-pin","maximize","maximize-2","menu","message-circle","message-square","mic","mic-off","minimize","minimize-2","minus","minus-circle","minus-square","monitor","moon","more-horizontal","more-vertical","move","music","navigation","navigation-2","octagon","package","paperclip","pause","pause-circle","percent","phone","phone-call","phone-forwarded","phone-incoming","phone-missed","phone-off","phone-outgoing","pie-chart","play","play-circle","plus","plus-circle","plus-square","pocket","power","printer","radio","refresh-ccw","refresh-cw","repeat","rewind","rotate-ccw","rotate-cw","rss","save","scissors","search","send","server","settings","share","share-2","shield","shield-off","shopping-bag","shopping-cart","shuffle","sidebar","skip-back","skip-forward","slack","slash","sliders","smartphone","speaker","square","star","stop-circle","sun","sunrise","sunset","tablet","tag","target","terminal","thermometer","thumbs-down","thumbs-up","toggle-left","toggle-right","trash","trash-2","trending-down","trending-up","triangle","truck","tv","twitter","type","umbrella","underline","unlock","upload","upload-cloud","user","user-check","user-minus","user-plus","user-x","users","video","video-off","voicemail","volume","volume-1","volume-2","volume-x","watch","wifi","wifi-off","wind","x","x-circle","x-square","youtube","zap","zap-off","zoom-in","zoom-out"
];

View File

@@ -0,0 +1,309 @@
import React from 'react';
import {observer, inject} from 'mobx-react';
import {
Dialog, FlatButton, RaisedButton,
Step,
StepLabel,
Stepper,
IconButton,
} from "material-ui";
import {DIALOG} from "../../../stores/global_ui";
import CategoryData from './CategoryData';
import ArrowForwardIcon from 'material-ui/svg-icons/navigation/arrow-forward';
import NavigationArrowBack from 'material-ui/svg-icons/navigation/arrow-back';
import schema from 'async-validator'
@inject('appstate')
@observer
export default class ItemDialog extends React.Component {
constructor(props) {
super(props);
this.props = props;
this.state = {
stepIndex: 0,
formData: {},
finished: false,
openedDialog: false,
errorMessage: ''
};
this.defaultState = Object.assign({}, this.state);
this.globalUI = props.appstate.globalUI;
this.customMenu = props.appstate.custom_menu;
}
componentDidMount() {
this.setState({
stepIndex: 0
});
}
onChangeForm(formData) {
this.setState({formData});
}
getStepContent(stepIndex) {
const {mode="create", defaultValue={}} = this.props;
switch (stepIndex) {
case 0:
return (
<CategoryData
mode={mode}
defaultValue={defaultValue}
onChangeData={formData => this.setState({formData})}/>
);
// case 1:
// return <IdentificationPassport/>;
}
}
handleOpen = () => {
this.setState({confirmationDialog: true})
};
handleNext = () => {
const {stepIndex} = this.state;
if (stepIndex === 0) {
const rules = {
name: [
{
required: true,
message: 'Please insert name'
}
],
icon: [
{
required: true,
message: 'Please insert icon'
}
],
};
if(this.state.formData.type == 'url'){
rules.url = [
{
required : true,
message :'Please insert valid url'
}
]
}
else if(this.state.formData.type == "post"){
rules.tag = [
{
required : true,
message : "Please insert post category"
}
];
rules.post_template = [
{
required : true,
message : "Please insert post template"
}
]
}
const validator = new schema(rules);
validator.validate(this.state.formData, (errs, f) => {
console.log(errs);
if (errs) {
console.log(this.state.formData,'this is form data');
this.globalUI.showNotification("Something's Wrong", errs[0].message);
} else {
// if(this.state.formData.type == 'url' && !this.state.formData.url){
// this.globalUI.showNotification("Something's Wrong", 'Please input url',this.state.formData);
// return;
// }
// else if(this.state.formData.type == 'post' && !this.state.formData.tag){
// console.log(this.state.formData,'==========');
// this.globalUI.showNotification("Something's Wrong", 'Please input tag');
// return;
// }
this.setState({
stepIndex: stepIndex + 1,
});
}
});
}
};
handlePrev = () => {
const {stepIndex} = this.state;
if (stepIndex > 0) {
this.setState({stepIndex: stepIndex - 1});
}
};
closeDialog = ()=>{
this.customMenu.formData.name = "";
this.customMenu.formData.url = "";
this.globalUI.hideDialog(DIALOG.CUSTOM_MENU.CREATE)
}
handleClose = () => {
this.setState({confirmationDialog: false})
};
save = () => {
this.globalUI.hideDialog(DIALOG.CUSTOM_MENU.CREATE);
this.globalUI.showDialogLoading();
const {mode="create", defaultValue={}} = this.props;
let data = this.state.formData;
data.additional_data = (data.type == 'post') ? {tag_id : data.tag,template : data.post_template} :{};
delete data.tag;
delete data.post_template;
if (mode === "create") {
if(data.icon == ''){
data.icon = 'buffer';
}
this.customMenu.create(data)
.then(res => {
this.globalUI.hideDialogLoading();
this.globalUI.openSnackbar("Success Added New Custom Menu");
this.setState({
stepIndex: 0
});
})
.catch(err => {
this.globalUI.hideDialogLoading();
this.globalUI.openSnackbar("Something Goes Wrong");
this.setState({
stepIndex: 0
});
console.error(err);
});
} else if (mode === "update") {
if(data.icon == ''){
data.icon = 'buffer';
}
this.customMenu.update(defaultValue.id, this.state.formData)
.then(res => {
// this.globalUI.hideDialog(DIALOG.EMPLOYEE.CREATE);
this.globalUI.hideDialogLoading();
this.globalUI.openSnackbar("Success Updated")
this.setState({
stepIndex: 0
})
// this.classStore.getAll();
})
.catch(err => {
this.globalUI.openSnackbar("Error, Check log for detail");
console.error(err);
});
}
}
handlePost = () => {
// this.agentStore.post().then(res => {
// this.props.history.push(LINKS.SETTING);
// this.globalUI.openSnackbar("Successfull Added Employee");
// });
};
continueButton() {
if (this.state.stepIndex === 1) {
return (
<RaisedButton
label="Finish"
primary={true}
onClick={this.save}
/>
);
} else {
return (
<RaisedButton
label="Next"
primary={true}
onClick={this.handleNext}
/>
);
}
}
render() {
const {finished, stepIndex} = this.state;
const {mode="create", defaultValue={}} = this.props;
const actions = [
<RaisedButton
label="OK"
primary={true}
style={{marginRight: 10}}
onClick={this.handleClose}
/>,
]
const title =
<div>
<h4 style={{
fontSize: 26,
marginBottom: 0,
marginTop: 0,
fontWeight: 500,
color: "black"
}}>{(mode === "create") ? "Add" : "Update"} Custom Menu</h4>
</div>
;
return (
<div>
<Dialog
title={<div>
<div>{title}</div>
<div style={{padding: "0px 14px 0px 0px"}}>
<Stepper activeStep={stepIndex}>
<Step>
<StepLabel style={{padding: "0px 14px 0px 0px"}}>Menu Data</StepLabel>
</Step>
{/* <Step>
<StepLabel style={{padding: "0px 0px 0px 14px", height: 52}}>Identification & Passport</StepLabel>
</Step> */}
</Stepper>
</div>
</div>}
// titleStyle={{paddingBottom: 10}}
modal={false}
actions={<div style={{marginTop: 12}}>
<FlatButton
label={(stepIndex === 0) ? "Cancel" : "Back"}
style={{marginRight: 10}}
primary={true}
onClick={() => (stepIndex === 0) ? this.closeDialog() : this.handlePrev()}
/>
{this.continueButton()}
</div>}
autoScrollBodyContent={true}
repositionOnUpdate={true}
open={this.globalUI[DIALOG.CUSTOM_MENU.CREATE]}
onRequestClose={this.handleClose}
style={{zIndex: 999}}
>
<div>
{this.getStepContent(stepIndex)}
</div>
</Dialog>
<Dialog
title="Warning"
actions={actions}
modal={false}
autoScrollBodyContent={false}
contentStyle={{width: 350}}
open={this.state.confirmationDialog}
onRequestClose={() => this.handleClose()}
>
{this.state.errorMessage}
</Dialog>
</div>
)
}
}

View File

@@ -0,0 +1,238 @@
import React from 'react';
import {observer, inject} from 'mobx-react';
import bind from 'bind-decorator';
import {
Card,
CardActions,
CardHeader,
CardMedia,
CardTitle,
AutoComplete,
CardText,
FlatButton,
Divider,
RaisedButton,
Toolbar,
DatePicker,
FontIcon,
SelectField,
MenuItem,
ToolbarGroup,
FloatingActionButton,
ToolbarSeparator,
IconButton,
ToolbarTitle,
Table,
TableBody,
TableHeader,
TableHeaderColumn,
TableRow,
TableRowColumn,
TextField,
Paper,
RadioButton,
RadioButtonGroup,
DropDownMenu,
Dialog,
Tab, Tabs,
} from 'material-ui';
import {withRouter} from 'react-router';
import {BrowserRouter as Router, Route} from 'react-router-dom';
import StarBorder from 'material-ui/svg-icons/toggle/star-border';
import ContentAdd from 'material-ui/svg-icons/content/add';
import SwipeableViews from 'react-swipeable-views';
import SearchIcon from 'material-ui/svg-icons/action/search';
import AddIcon from 'material-ui/svg-icons/content/add';
import DeleteIcon from 'material-ui/svg-icons/content/delete-sweep';
import EmptyComponent from '../EmptyComponent';
import {DIALOG} from "../../stores/global_ui";
import DialogCreate from './Dialog';
import {startCase} from 'lodash'
import * as _ from 'lodash';
import '@mdi/font/css/materialdesignicons.min.css';
let DateTimeFormat = global.Intl.DateTimeFormat;
@inject('appstate')
@observer
export default class CustomMenus extends React.Component {
constructor(props) {
super(props);
this.props = props;
this.state = {
value: 0,
iniId:'',
edit : false,
mode : "create",
defaultValue : {}
};
this.handleChange = this
.handleChange
.bind(this);
this.defaultState = Object.assign({}, this.state);
this.http = props.appstate.http;
this.authStore = props.appstate.auth;
this.uiStore = props.appstate.uiStore;
this.globalUI = props.appstate.globalUI;
this.customMenus = props.appstate.custom_menu;
}
componentDidMount() {
this.globalUI.openLoading();
this.customMenus.getAll().then(res=>{
this.globalUI.closeLoading();
}).catch(err=>{
this.globalUI.closeLoading();
});
}
deleteClicked = (id) => {
this.setState({
id : id,
openedDelete: true
});
};
handleOpenEdit = (data)=>{
this.setState({
defaultValue : data,
mode : 'update'
},()=>this.globalUI.showDialog(DIALOG.CUSTOM_MENU.CREATE))
}
handleOpenDialog = (mode,Id) => {
this.setState({
mode : mode,
defaultValue : (Id == null) ? {} : {
id : Id
}
},()=>this.globalUI.showDialog(DIALOG.CUSTOM_MENU.CREATE));
};
handleClickDelete = (id) => {
this.customMenus.delete(id).then(res=>{
this.customMenus.getAll();
this.setState({
openedDelete: false,
openSnackbarDelete: true
});
this.globalUI.openSnackbar("Successful Deleted");
}).catch(err=>{
console.log(err);
this.globalUI.openSnackbar("Something Goes Wrong");
});
};
handleCloseDelete = () => {
this.setState({
openedDelete: false
})
};
handleChange = (event, index, value) => this.setState({value});
search = (event)=>{
if(event.target.value.length == 0){
this.customMenus.isSearching = false;
}
else{
this.customMenus.isSearching = true;
this.customMenus.search(event.target.value);
}
}
render() {
const actionsDelete = [
<FlatButton
label="Cancel"
primary={true}
onClick={this.handleCloseDelete}
/>,
<FlatButton
label="Delete"
primary={true}
onClick={() => this.handleClickDelete(this.state.id)}
/>,
];
return (
<Card className="animated fadeIn cardLite">
<Toolbar className="toolbarCard" style={{backgroundColor: '#fff'}}>
<ToolbarGroup>
<SearchIcon style={{marginRight: 8, color: "#999"}}/>
<TextField
hintText="Search Menu"
style={{fontSize: 14}}
hintStyle={{fontSize: 14}}
underlineShow={false}
onChange={this.search}
/>
</ToolbarGroup>
<ToolbarGroup className="ToolbarGroupLast">
<ToolbarSeparator/>
<RaisedButton className="ToolbarGroupLastButton" icon={<AddIcon/>} label="New Menu"
primary={true} onClick={()=>this.handleOpenDialog("create",null)}/>
</ToolbarGroup>
</Toolbar>
<Divider/>
<div style={{paddingBottom: 5}}>
<Table selectable={false}
fixedHeader={true}
height={'calc(100vh - 280px)'}>
<TableHeader displaySelectAll={false}
adjustForCheckbox={false}
enableSelectAll={false}>
<TableRow style={{height: 38, background: '#f6f9fc'}}>
<TableHeaderColumn className="TableHeaderColumnAkun"
style={{height: 'auto'}}>Name</TableHeaderColumn>
<TableHeaderColumn className="TableHeaderColumnAkun"
style={{height: 'auto'}}>Type</TableHeaderColumn>
<TableHeaderColumn className="TableHeaderColumnAkun"
style={{height: 'auto', textAlign: 'right'}}>Action</TableHeaderColumn>
</TableRow>
</TableHeader>
<TableBody displayRowCheckbox={false}>
{(!this.customMenus.isEmpty) ? (this.customMenus.isSearching ? this.customMenus.dataFiltered : this.customMenus.data).map((item, index) => {
return (
<TableRow key={item.id}>
<TableRowColumn>
<div style={{color : '#6772e5',cursor : 'pointer'}} onClick={()=>this.handleOpenEdit(item)}>
{item.name}
</div>
</TableRowColumn>
<TableRowColumn>
{startCase(item.type)}
</TableRowColumn>
<TableRowColumn style={{textAlign: "right"}}><IconButton
tooltip="Delete"
className="ToolbarGroupLastButton"
onClick={() => this.deleteClicked(item.id)}><DeleteIcon color="#999999"
className="iconSmallButton"/></IconButton></TableRowColumn>
</TableRow>
);
}) : (<TableRow>
<TableRowColumn colSpan="4" style={{}}>
<EmptyComponent type="empty" header="" content="There is no data in sight"/>
</TableRowColumn>
</TableRow>)
}
</TableBody>
</Table>
</div>
<Dialog
title="Warning"
actions={actionsDelete}
modal={true}
open={this.state.openedDelete}
onRequestClose={() => this.handleCloseDelete()}
>
Are you sure want to delete this?
</Dialog>
<DialogCreate mode={this.state.mode} defaultValue={this.state.defaultValue}/>
</Card>
)
}
}