Initial commit
This commit is contained in:
7
src/client/global.scss
Normal file
7
src/client/global.scss
Normal file
@@ -0,0 +1,7 @@
|
||||
.text-right {
|
||||
text-align: right
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center
|
||||
}
|
||||
79
src/client/index.js
Normal file
79
src/client/index.js
Normal file
@@ -0,0 +1,79 @@
|
||||
import '@babel/register';
|
||||
import '@babel/polyfill';
|
||||
|
||||
import 'antd/dist/antd.min';
|
||||
import 'antd/dist/antd.min.css';
|
||||
|
||||
import './global.scss';
|
||||
import 'react-responsive-carousel/lib/styles/carousel.css';
|
||||
|
||||
|
||||
import React from 'react';
|
||||
import {Helmet} from "react-helmet";
|
||||
import {render} from 'react-dom';
|
||||
import {Provider} from 'mobx-react';
|
||||
import {BrowserRouter, Route} from 'react-router-dom';
|
||||
|
||||
window.moment = require('moment');
|
||||
// require(`imports-loader?this=>window,fix=>module.exports=0!snapsvg/dist/snap.svg.js`);
|
||||
|
||||
import AppState from '../common/stores/appstate';
|
||||
import Routes from '../common/routes';
|
||||
import RootComponent from "../common/pages/Root";
|
||||
import { LocaleProvider } from 'antd';
|
||||
import enUS from 'antd/lib/locale-provider/en_US';
|
||||
import {getMobileOperatingSystem} from "../common/stores/firebase";
|
||||
import cinnamonSugar from "cinnamon-sugar";
|
||||
import ButterToast from "butter-toast";
|
||||
import * as firebase from "firebase";
|
||||
|
||||
// var injectTapEventPlugin = require("react-tap-event-plugin");
|
||||
// injectTapEventPlugin();
|
||||
|
||||
const initialState = window.__INITIAL_STATE__ || {};
|
||||
|
||||
const appstate = new AppState(Object.assign({
|
||||
token: localStorage.getItem('id_token') || '',
|
||||
userData: {
|
||||
}
|
||||
}, initialState));
|
||||
|
||||
|
||||
// if (getMobileOperatingSystem() !== 'iOS') {
|
||||
firebase.messaging().onMessage((payload) => {
|
||||
console.log("Message received cok.", payload);
|
||||
// alert(payload.notification.body);
|
||||
|
||||
if(payload.data.new_message){
|
||||
appstate.message.pushNewMessage(payload.data);
|
||||
}
|
||||
|
||||
if(payload.data.notification_type == 'notification'){
|
||||
appstate.notification.unread_notif+=1
|
||||
}
|
||||
const toast = cinnamonSugar({
|
||||
kind: 'crisp',
|
||||
theme: 'info',
|
||||
// picture: 'http://lorempixel.com/150/150/people',
|
||||
title: <a href={'inbox/'}>{payload.notification.title}</a>, // you can also add jsx code here!
|
||||
// message: JSON.stringify(payload), // you can also add jsx code here!
|
||||
message: payload.notification.body, // you can also add jsx code here!
|
||||
toastTimeout: 4000,
|
||||
icon: 'bell' // literally any font awesome 4.7 icon
|
||||
// you may also add here regular butter-toast options, such as toastTimeout,
|
||||
// name, sticky, etc..
|
||||
});
|
||||
ButterToast.raise(toast)
|
||||
});
|
||||
// }
|
||||
|
||||
render(
|
||||
<Provider appstate={ appstate }>
|
||||
<LocaleProvider locale={enUS}>
|
||||
<BrowserRouter>
|
||||
<Route path='/' component={RootComponent} />
|
||||
</BrowserRouter>
|
||||
</LocaleProvider>
|
||||
</Provider>,
|
||||
document.getElementById('root')
|
||||
);
|
||||
36
src/common/components/Alert/index.js
Normal file
36
src/common/components/Alert/index.js
Normal file
@@ -0,0 +1,36 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import Dialog from 'material-ui/Dialog';
|
||||
import FlatButton from 'material-ui/FlatButton';
|
||||
import RaisedButton from 'material-ui/RaisedButton';
|
||||
import {DIALOG} from "../../stores/global_ui";
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class Alert extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
}
|
||||
|
||||
render() {
|
||||
const actions = [
|
||||
<FlatButton
|
||||
label="OK"
|
||||
primary={true}
|
||||
onClick={() => this.props.appstate.globalUI.hideAlert()}
|
||||
/>,
|
||||
];
|
||||
|
||||
return (<div>
|
||||
<Dialog
|
||||
actions={actions}
|
||||
modal={false}
|
||||
open={this.props.appstate.globalUI[DIALOG.UI.ALERT]}
|
||||
onRequestClose={() => this.props.appstate.globalUI.hideAlert()}
|
||||
>
|
||||
{this.props.appstate.globalUI.globalAlert}
|
||||
</Dialog>
|
||||
</div>);
|
||||
}
|
||||
}
|
||||
61
src/common/components/ConfirmationDialog/index.js
Normal file
61
src/common/components/ConfirmationDialog/index.js
Normal file
@@ -0,0 +1,61 @@
|
||||
import React from 'react';
|
||||
import Dialog from 'material-ui/Dialog';
|
||||
import FlatButton from 'material-ui/FlatButton';
|
||||
import RaisedButton from 'material-ui/RaisedButton';
|
||||
import { confirmable } from 'react-confirm';
|
||||
|
||||
import lightBaseTheme from 'material-ui/styles/baseThemes/lightBaseTheme';
|
||||
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
|
||||
import getMuiTheme from 'material-ui/styles/getMuiTheme';
|
||||
|
||||
const Theme = (props) => (
|
||||
<MuiThemeProvider muiTheme={getMuiTheme(lightBaseTheme)}>
|
||||
{ props.children }
|
||||
</MuiThemeProvider>
|
||||
);
|
||||
|
||||
class Confirmation extends React.Component {
|
||||
|
||||
render() {
|
||||
const {
|
||||
okLabel = 'OK',
|
||||
cancelLabel = 'Cancel',
|
||||
title,
|
||||
confirmation,
|
||||
show,
|
||||
proceed,
|
||||
dismiss,
|
||||
cancel,
|
||||
modal,
|
||||
} = this.props;
|
||||
|
||||
const actions = [
|
||||
<FlatButton
|
||||
label={cancelLabel}
|
||||
secondary={true}
|
||||
onClick={cancel}
|
||||
/>,
|
||||
<FlatButton
|
||||
label={okLabel}
|
||||
primary={true}
|
||||
onClick={proceed}
|
||||
/>,
|
||||
];
|
||||
|
||||
return (
|
||||
<Theme>
|
||||
<Dialog
|
||||
title={title}
|
||||
actions={actions}
|
||||
modal={modal}
|
||||
open={show}
|
||||
onRequestClose={dismiss}
|
||||
>
|
||||
{confirmation}
|
||||
</Dialog>
|
||||
</Theme>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default confirmable(Confirmation);
|
||||
38
src/common/config/app.js
Normal file
38
src/common/config/app.js
Normal file
@@ -0,0 +1,38 @@
|
||||
const appConfigDev = {
|
||||
apiUrl: "http://localhost:8823/v1/",
|
||||
imageUrl: "http://localhost:8823"
|
||||
};
|
||||
|
||||
const appConfigProd = {
|
||||
apiUrl: '',
|
||||
imageUrl: ''
|
||||
}
|
||||
|
||||
// if (typeof window != 'undefined' && window.PRODUCTION) {
|
||||
// appConfig = appConfigProd
|
||||
// } else {
|
||||
// appConfig = appConfigDev
|
||||
// }
|
||||
|
||||
let apiUrl;
|
||||
let imageUrl;
|
||||
let appUrl;
|
||||
let type = 'akuntiket';
|
||||
|
||||
// apiUrl = "https://marketplace-sillyfish-staging-api.asacreative.com/v1/";
|
||||
// imageUrl = "https://marketplace-sillyfish-staging-api.asacreative.com";
|
||||
apiUrl = "https://marketplace-sillyfish-api.asacreative.com/v1/";
|
||||
imageUrl = "https://marketplace-sillyfish-api.asacreative.com";
|
||||
type = 'localhost';
|
||||
if(window.location.href.includes("localhost") || window.location.href.includes("marketplace-store")){
|
||||
appUrl = 'http://localhost:7700'
|
||||
}else{
|
||||
appUrl = 'https://sillyfish.asacreative.com';
|
||||
}
|
||||
|
||||
export const appConfig = {
|
||||
apiUrl: apiUrl,
|
||||
imageUrl: imageUrl,
|
||||
appUrl: appUrl,
|
||||
type
|
||||
};
|
||||
569
src/common/config/const.js
Normal file
569
src/common/config/const.js
Normal file
@@ -0,0 +1,569 @@
|
||||
//used for storing static masterdata uuid, don't put firebase config in here, put it on app.ts
|
||||
export const constant = {
|
||||
ITEM_STATUS: {
|
||||
IN_STOCK: '2b1a2598-8333-4b19-ae7b-c054bec87540',
|
||||
OUT_OF_STOCK: 'a3f7e153-19d3-4cc0-bd38-817f3ba0f1ee'
|
||||
},
|
||||
ORDER_STATUSES: {
|
||||
WAITING_PAYMENT_APPROVAL: 'd90a61ff-1e73-4cdb-94f3-7abfe21f6bb3',
|
||||
ON_SHIPPING: '1a702d90-3dc9-4d86-9b92-cdd5275583d9',
|
||||
ON_SHIPPING_RETRY : 'aff90aec-510f-4cc5-8a68-4ecf79507957',
|
||||
SHIPPING_COMPLETE: 'c68114ca-cd67-4fb7-80b2-ef271d98c26f',
|
||||
WAITING_STORE_RESPONSE: '01c6eed7-9fcb-4c9e-bebf-16173d901711',
|
||||
CANCELLED_BY_STORE: 'c341db97-61bf-4342-8462-8999c05f409f',
|
||||
PENDING_PAYMENT: 'a4b9cf81-3d74-486e-a02e-66b345c1a0a2',
|
||||
FAILED: '2f7351d7-75b8-438f-a497-850cea1c5af1',
|
||||
PROCESSING: '8fb76bff-6320-4548-9403-90b7c41709c4',
|
||||
COMPLETED: '436edb52-7961-40a3-94a2-f8450dc19651',
|
||||
ON_HOLD: '18fb976f-5a8c-47b0-80c7-58daddb4ad32',
|
||||
CANCELLED: 'a72c48ba-c750-4f74-85fb-ed8a18df07b9',
|
||||
PREORDER_WAITING_STORE_RESPONSE : 'b1acd4c8-8b4d-4ab4-852e-a484a9afefc4',
|
||||
PREORDER_WAITING_BUYER_CONFIRMATION : '9b35697a-b0e9-479f-9840-e988d36b4970',
|
||||
PREORDER_BUYER_DECLINE : '047d13ac-4181-419a-beef-b6e5a0344db0',
|
||||
PREORDER_WAITING_PAYMENT : 'ca1a849e-09cf-46bc-8125-b3cf32aa2cb9'
|
||||
},
|
||||
SHIPPING_METHOD :{
|
||||
GOJEK_SAME_DAY : '64defc8f-5d7f-466c-8712-9a4243a9f893',
|
||||
JT_EXPRESS : "77d411a2-1b29-488d-99dd-d23b03a22d6c",
|
||||
JNE_REG : "c17d6cad-143b-4842-a1e3-8024367a38ea",
|
||||
JNE_OKE : "6e015d5f-1b3f-46f6-8f95-901617b36b21",
|
||||
POS_KILAT : "e418cdd9-48c1-459e-a231-3d84693fa937",
|
||||
GOJEK_INSTANT : "739b187b-2a88-4532-97c1-c78eab0d7bad"
|
||||
},
|
||||
USER_TYPE: {
|
||||
ADMINISTRATOR: '4a30a59c-0ed1-44a7-9480-083e79869586',
|
||||
MEMBER: '96a23c36-0718-423f-91f3-fdba79a8e526',
|
||||
STORE: 'ef60b250-8d44-45f7-8b27-18a9bc4ad723',
|
||||
TEMPORARY: 'b2f8affa-ce2f-420b-ba6a-af3afa9fe881'
|
||||
},
|
||||
COA_TYPE: {
|
||||
ASSETS: 'a89320b5-485c-47f6-be36-a927c6ccef78',
|
||||
WALLET: '1557bdcf-3350-4ffc-ab9e-831b8dd0ceca',
|
||||
PENDING_PAYMENT_TO_WALLET: '0b58cf68-bc58-42d3-be9e-0ae085f77909',
|
||||
PENDING_SYSTEM_FEE: '88e1c4fe-1c7b-4db5-be66-870fa9fbf5e0',
|
||||
PENDING_REVENUE: '8fc0460b-31c6-44f6-ad11-72ee22a4df8f',
|
||||
SYSTEM_FEE: '0efb0a23-1adc-4131-8122-b0a706d650b3',
|
||||
LIABILITY: 'c73323aa-21b8-4333-b76d-f77dd64aaddd',
|
||||
BANK: '9d6e3006-16cd-4422-8244-9e6424b659f0',
|
||||
REVENUE: 'ee820656-fa7c-4a89-a401-e896f15253e7'
|
||||
},
|
||||
TRANSACTION_TYPE: {
|
||||
WITHDRAW: '6fe82a7e-078b-487f-8134-a34ca6d6b740',
|
||||
ORDER_PAYMENT: 'e5cd3234-7361-4551-ba25-c63bf5ac39b1',
|
||||
ORDER_CANCEL: '6cba5a8f-5ede-43fc-9a5b-58ffbe545147',
|
||||
ORDER_FINISH: 'c73323aa-21b8-4333-b76d-f77dd64aaddd',
|
||||
MOVE_PAYMENT_GATEWAY_TO_BANK: '9e497222-d320-450d-8f2e-e8f98de0a086'
|
||||
},
|
||||
PROVINCE: {
|
||||
"Bali":"50ed235f-763e-4ece-aa7f-262ae293c0c6",
|
||||
"Bangka Belitung":"8a11abf8-223a-4050-92d8-04747f8dc776",
|
||||
"Banten":"549549ae-9396-4a3e-84cf-cd903d98a5b7",
|
||||
"Bengkulu":"824f00ff-9d51-4ea2-93fe-6e758c4f6ad9",
|
||||
"DI Yogyakarta":"a87a0ed4-13d8-4e34-96fd-419645f20d91",
|
||||
"DKI Jakarta":"b5b6a32e-d6b2-49b0-bdb9-27d69529d1da",
|
||||
"Gorontalo":"f35fd3a5-e892-4aa4-ad31-6202fe7d589b",
|
||||
"Jambi":"16b1fa40-24bb-4ec4-ab32-4824d39a588f",
|
||||
"Jawa Barat":"ec922735-8779-4820-93a3-0cbfd9a9fdc0",
|
||||
"Jawa Tengah":"a52ef858-4560-462c-90b7-e1a207492617",
|
||||
"Jawa Timur":"8f0ca362-bb14-440e-8ea2-9e26f32d6eaf",
|
||||
"Kalimantan Barat":"bd5834e1-4c43-4c1e-b746-a98cbae19940",
|
||||
"Kalimantan Selatan":"c26da6bc-f8be-4375-b487-c995358456f5",
|
||||
"Kalimantan Tengah":"ec2d9809-0d1f-413e-9db6-58ecec2c2c4d",
|
||||
"Kalimantan Timur":"af8e73a8-64a6-41ca-8f7e-e00920f832f6",
|
||||
"Kalimantan Utara":"d6866e25-7ff6-444d-b165-60fb287386d5",
|
||||
"Kepulauan Riau":"341efa54-6889-4b62-96c3-4188b9c7ca3d",
|
||||
"Lampung":"9a5303f0-d3ba-49d5-af74-29c3fd3f059f",
|
||||
"Maluku":"0f354c29-87a4-4cf9-927c-bbc373e7a5b3",
|
||||
"Maluku Utara":"2df802e2-0a3d-4b06-87bf-da5b798158fa",
|
||||
"Nanggroe Aceh Darussalam (NAD)":"046b90f5-a713-4059-bf4e-4dccfc40aa64",
|
||||
"Nusa Tenggara Barat (NTB)":"93254dff-fc4f-49c3-afd2-ae4f01c0d80d",
|
||||
"Nusa Tenggara Timur (NTT)":"60a7795a-4a09-419e-977d-290b9706c071",
|
||||
"Papua":"35d4d6b1-c3f2-4d8d-aad3-1063faf9d4b7",
|
||||
"Papua Barat":"af18dbeb-7ade-4592-9f04-b4ab4b8a782f",
|
||||
"Riau":"c3f4604d-e7ae-4fcd-8a82-1c09c6298f14",
|
||||
"Sulawesi Barat":"191c5e44-c7da-4274-ba00-ef039ba0e193",
|
||||
"Sulawesi Selatan":"5288c692-8f9c-463a-9b0d-807116e520a9",
|
||||
"Sulawesi Tengah":"d1814e09-73a2-4d10-a0a1-316b8af562c3",
|
||||
"Sulawesi Tenggara":"9b295028-c9e5-4852-9330-d25f92b74b71",
|
||||
"Sulawesi Utara":"5bd62ea2-fc35-46fa-aa97-661e355d78e9",
|
||||
"Sumatera Barat":"8985eb3c-235c-4df3-9a99-aa97db7558f0",
|
||||
"Sumatera Selatan":"d63530b8-6e46-4402-86ff-8d45f63a4888",
|
||||
"Sumatera Utara":"6c568310-28bb-47e1-8c8f-2680107face5",
|
||||
},
|
||||
CITY: {
|
||||
"Aceh Barat": "b1e33620-fd02-4ea0-b0cd-242d19dcf561",
|
||||
"Aceh Barat Daya": "28438a41-bda5-4851-adc9-3ec7e6568d73",
|
||||
"Aceh Besar": "a4542e75-64a5-4e1a-b66e-fa17185a055e",
|
||||
"Aceh Jaya": "b58be43c-af10-4424-9b3d-2d168df73776",
|
||||
"Aceh Selatan": "5efa2a1b-ba60-4438-976a-a534e36de2f5",
|
||||
"Aceh Singkil": "f6157650-d407-410e-9169-4c4065b6d7b0",
|
||||
"Aceh Tamiang": "34bac717-f5d6-4492-8c02-16a2de96fefc",
|
||||
"Aceh Tengah": "6c000418-41de-43eb-b462-587760a5af04",
|
||||
"Aceh Tenggara": "bf964c26-6bfd-43de-9f2e-fcbc4a933f1d",
|
||||
"Aceh Timur": "d9e18f57-8877-454f-abb6-5a566d7362a1",
|
||||
"Aceh Utara": "a671fd98-20fe-42ed-a7ca-171d9f0de068",
|
||||
"Agam": "62cec5a8-7c58-431e-aeb9-f5cb9d46561c",
|
||||
"Alor": "f80649f7-e236-45a8-8a86-c9c52b8381c2",
|
||||
"Ambon": "6fbef7b1-86a0-45e8-9dd3-2e48eabbc9a9",
|
||||
"Asahan": "8eb8afbf-c68b-4b1e-a5ff-ca05a73d6c35",
|
||||
"Asmat": "b98f9021-62b4-4fa0-b27e-83d79e4b89a1",
|
||||
"Badung": "da52afd2-e29b-4c4d-924c-a092c452b65a",
|
||||
"Balangan": "bb0d86cd-07d5-4d17-a635-ffc1dfb03efe",
|
||||
"Balikpapan": "2a947634-ccf4-4bf0-aa4f-de12078e862d",
|
||||
"Banda Aceh": "effd51fc-0f5e-43ee-9d21-4c1e54acb591",
|
||||
"Bandar Lampung": "487de185-a12c-46fa-a8ce-4fc79066c9b2",
|
||||
"Bandung": "87ed2b71-1a24-4852-882e-47d6ff6e2ca7",
|
||||
"Bandung Barat": "ec358bdf-808e-410d-bca9-d25f9bba491e",
|
||||
"Banggai": "5a632a36-5bf6-468b-8ef7-11ad935ccb1a",
|
||||
"Banggai Kepulauan": "730c3ad8-9303-4879-9740-116f1677e5b6",
|
||||
"Bangka": "ed3fc28f-6ab8-4fc1-a5e0-5a55e9b47305",
|
||||
"Bangka Barat": "2704fd8f-76e6-4ef3-b2ba-82fb63c2ef9a",
|
||||
"Bangka Selatan": "49cdc47e-2b44-437f-9e93-c05d57000b77",
|
||||
"Bangka Tengah": "bb457319-faac-4416-a6fe-6f11dd619834",
|
||||
"Bangkalan": "b594222e-fb7a-47d2-9193-ff1ff60e1a43",
|
||||
"Bangli": "7149533c-606f-42fa-bd08-dff74d70048f",
|
||||
"Banjar": "0c671596-c928-4ca4-89d2-a7f4211cf923",
|
||||
"Banjarbaru": "451c974c-ab6c-4452-8563-c0416ccd1002",
|
||||
"Banjarmasin": "98e47369-c058-48b4-8ea8-f01dc8e9af03",
|
||||
"Banjarnegara": "c3cf7d3f-a78e-472c-8d2b-f5546f5e6997",
|
||||
"Bantaeng": "33b0a535-56c6-4c64-af3b-4eb4a4f1e6cc",
|
||||
"Bantul": "cdf49131-9424-49b5-b9d7-bc7bf14cc283",
|
||||
"Banyuasin": "45264c1f-e98f-4352-af17-db697d1b1173",
|
||||
"Banyumas": "a7923cb1-f461-4429-b716-0de2b7d9db36",
|
||||
"Banyuwangi": "3fd259eb-8847-400f-913f-c8d406353b1f",
|
||||
"Barito Kuala": "0b3407d5-70ce-40f8-a051-462bca5b674d",
|
||||
"Barito Selatan": "6d444a19-44a6-42c8-9f54-99d490e0ad4d",
|
||||
"Barito Timur": "fc00f37c-273a-40f8-852f-a788c693483e",
|
||||
"Barito Utara": "fca44370-2054-4e83-81f1-f4ed9b1a4cd4",
|
||||
"Barru": "5922c28f-14af-4ddc-a89b-55d5b2516fc0",
|
||||
"Batam": "ac12d38b-6075-4bcc-88e3-daa175e94e72",
|
||||
"Batang": "d5bfbc77-d95a-45a5-814e-da3abd888c0c",
|
||||
"Batang Hari": "60022238-b41f-4b92-a724-1494d2f48c75",
|
||||
"Batu": "6a62c33c-ef43-4f38-ac84-41e83563e081",
|
||||
"Batu Bara": "372ce28e-1a13-4626-8f13-3bf79d2c9161",
|
||||
"Bau-Bau": "fc4a2ea0-f96f-41b4-b84e-be1b6aad0668",
|
||||
"Bekasi": "89418eb6-0c3f-4c07-ae3a-524f0af02ae5",
|
||||
"Belitung": "c13e5b10-7918-4bff-a8f7-390be26357f8",
|
||||
"Belitung Timur": "5fb6ed3f-d0ba-46ce-aea5-9d67f78bf125",
|
||||
"Belu": "483ae17f-d42c-4e5c-9b3b-a4c291e0414b",
|
||||
"Bener Meriah": "23ae9489-65e5-4435-b8fc-98c9df0d7a56",
|
||||
"Bengkalis": "2d031c8a-6e7b-4384-917c-e69afc2c4cbc",
|
||||
"Bengkayang": "c1c0712b-e4bf-4d81-9aa3-b4c1dcd6d4a9",
|
||||
"Bengkulu": "c7d9eed1-76ff-4ee9-a21d-17bae301c646",
|
||||
"Bengkulu Selatan": "b6848fc9-f774-4475-b45b-947de7698ffc",
|
||||
"Bengkulu Tengah": "01a1d267-4158-45b1-874a-306844104d35",
|
||||
"Bengkulu Utara": "a0ccdc76-6a2b-4c05-9bed-687cdd991d67",
|
||||
"Berau": "cd5d7492-49be-4f43-9b18-b78c399b1f45",
|
||||
"Biak Numfor": "43314eb6-e59e-4e9b-9a5d-c08aaf7d662e",
|
||||
"Bima": "a8043d28-50a7-47be-86aa-3b19d762a9c0",
|
||||
"Binjai": "e574e0ba-18ee-4028-97bd-99658923fd9f",
|
||||
"Bintan": "31b8f874-b3db-4373-9556-cbc2f29b0310",
|
||||
"Bireuen": "eea7931c-2a39-4712-83e5-ac54fc0b9e0e",
|
||||
"Bitung": "b982a56c-478c-47fe-acfd-2a022d03fc9f",
|
||||
"Blitar": "24475ccf-0964-47d4-beae-839c30b1081b",
|
||||
"Blora": "13fa91a3-2e3c-41bd-b77d-7461910dfc0b",
|
||||
"Boalemo": "dcdd4654-bdcb-4e20-8f75-3a634d2ba15f",
|
||||
"Bogor": "efd1f567-ed57-43ed-9c27-1af2274b7c90",
|
||||
"Bojonegoro": "e6531746-0361-4c32-b51c-32c5387857bc",
|
||||
"Bolaang Mongondow (Bolmong)": "8c5602bd-1160-434b-85bc-b6798cb74582",
|
||||
"Bolaang Mongondow Selatan": "0d2072c1-1ec7-4d63-8cc9-e01a7cddaa44",
|
||||
"Bolaang Mongondow Timur": "c349d8f6-9019-4df1-a1de-be95ceeee83c",
|
||||
"Bolaang Mongondow Utara": "4a9be7d8-948d-40f3-aea9-124b42e3593d",
|
||||
"Bombana": "57017e44-992d-457c-b8cf-809148441f33",
|
||||
"Bondowoso": "5e24f72b-1607-497d-8bdd-58c44929f963",
|
||||
"Bone": "0fad4cf9-1901-462d-b825-45c0b091b785",
|
||||
"Bone Bolango": "b3e00a70-f833-4c97-b631-41bc5851996c",
|
||||
"Bontang": "02060391-f80f-409c-a29f-ecac9a99e406",
|
||||
"Boven Digoel": "b9b5c4cb-c16d-4927-9491-cf608d09d67b",
|
||||
"Boyolali": "4b1552b5-a5ee-43fd-ba60-cc3018dd767b",
|
||||
"Brebes": "1a263525-d6e1-4965-8b57-f320e867db22",
|
||||
"Bukittinggi": "110ec7af-85a4-458c-95fe-fc5ed614ddae",
|
||||
"Buleleng": "775b25b2-0cae-4288-8970-d7b3d97ecf5c",
|
||||
"Bulukumba": "73dfe021-f54e-4ddd-9ac9-04d9fdc3e49e",
|
||||
"Bulungan (Bulongan)": "a74bf2ac-91cc-4300-894a-c466176f0447",
|
||||
"Bungo": "2987e068-0f00-461e-a623-b3958f7f5eee",
|
||||
"Buol": "b6d03972-9836-411d-a97f-4d969a7826f6",
|
||||
"Buru": "56d850e1-035c-43b3-a82d-a3f1437eba06",
|
||||
"Buru Selatan": "ff49d3eb-a6ec-4eff-9c57-dfec2130e59c",
|
||||
"Buton": "ef12b971-54ce-417b-9138-d97f4413bb92",
|
||||
"Buton Utara": "f520ab48-4f1d-4510-834b-28b95fb0654f",
|
||||
"Ciamis": "95ef93ed-00fe-4f29-b197-da6c9648e81f",
|
||||
"Cianjur": "f82adeeb-6da3-4da5-a90c-333e16ec6e32",
|
||||
"Cilacap": "f63292ab-a87f-495e-9aa8-ec51eed0f817",
|
||||
"Cilegon": "7260ed81-8ed6-4240-bf01-9cea8c986fe3",
|
||||
"Cimahi": "ea4245ed-14e0-45d3-9440-f38b3d9c8da6",
|
||||
"Cirebon": "8639ab82-e2c1-47ea-99e7-cfb4b28d23c7",
|
||||
"Dairi": "907c950b-1cb2-42b6-87b0-bd4e34ce5483",
|
||||
"Deiyai (Deliyai)": "6ac05f2e-7920-4624-a9b4-df854b45f6a5",
|
||||
"Deli Serdang": "0363953d-4ea9-4e72-8fa6-8a2f527fa832",
|
||||
"Demak": "5c9f85c9-9e12-42ce-aec0-28569f1e781c",
|
||||
"Denpasar": "36eb40e4-4861-4918-b996-05327e474006",
|
||||
"Depok": "c5c58d39-7d03-46b8-9a9d-c0177b069ba9",
|
||||
"Dharmasraya": "135c7079-4fcb-4216-bf3b-a9a4c67f71c5",
|
||||
"Dogiyai": "b1687103-687a-4a1b-86fd-30a39256939a",
|
||||
"Dompu": "3ed353c9-9b72-4cc6-bc2a-cd52e7d9876c",
|
||||
"Donggala": "f757ad0f-949f-4aa0-be68-e8d8e41172e0",
|
||||
"Dumai": "2c3bd8ce-c62d-4ed3-9a09-a101049719f9",
|
||||
"Empat Lawang": "ebce1c41-4484-45dc-940d-f25d33d1adf6",
|
||||
"Ende": "3e29479f-b826-4250-b80f-298dc041dfd6",
|
||||
"Enrekang": "521e35ee-92ed-426e-b4d5-29ef9f723833",
|
||||
"Fakfak": "ad266cfa-a95c-4e4b-ad98-36fde4766c25",
|
||||
"Flores Timur": "6a224007-b6e8-4607-b720-b3696072fbb3",
|
||||
"Garut": "bd665464-abcd-4b06-8ee4-78731b5b006b",
|
||||
"Gayo Lues": "387779f5-c89c-44bf-8bed-9f298c783626",
|
||||
"Gianyar": "903cb88a-c202-425d-95fe-eac0c54298f5",
|
||||
"Gorontalo": "58851c48-7c94-450d-90e9-1f9d838783ba",
|
||||
"Gorontalo Utara": "98f3513c-e356-4480-a669-9d358ad08b73",
|
||||
"Gowa": "222a9819-f83e-489f-81cb-3ce6ca4c9ade",
|
||||
"Gresik": "e9c7f46e-644b-4a30-899d-742b9fa095a6",
|
||||
"Grobogan": "ec49000c-ba66-4f2f-8f00-d81f0ded7107",
|
||||
"Gunung Kidul": "7011dd04-04d1-442c-b2c0-47583383c0df",
|
||||
"Gunung Mas": "87b278e8-8946-498b-9ea4-15b4ab4b38f8",
|
||||
"Gunungsitoli": "3fd9b2d9-f906-40d5-a5fd-21ff9ec3cd72",
|
||||
"Halmahera Barat": "3e9a3663-ee5d-4909-b16b-69f500d633cc",
|
||||
"Halmahera Selatan": "1cbdced5-cfbb-46e8-b447-1ff376074f8e",
|
||||
"Halmahera Tengah": "ae091ed1-54a0-481a-8bb4-c7b945f401a4",
|
||||
"Halmahera Timur": "d0ff8b56-7d04-48a8-9858-85059b2737a0",
|
||||
"Halmahera Utara": "e3d2610f-f440-4f99-b922-688e680ba1f4",
|
||||
"Hulu Sungai Selatan": "fb91c398-118f-4d43-9a00-3916a94f58bc",
|
||||
"Hulu Sungai Tengah": "e94506f0-3e72-4490-acf0-e34f4810975d",
|
||||
"Hulu Sungai Utara": "f91a641f-4bb7-47e3-95b3-f68ba42d0f81",
|
||||
"Humbang Hasundutan": "d0eea20a-377e-4f43-968c-d3086cd1373a",
|
||||
"Indragiri Hilir": "a6236e07-a5c6-4860-89d1-82d3f4d902cb",
|
||||
"Indragiri Hulu": "407d004c-cec9-45ba-97e5-16afc06505bb",
|
||||
"Indramayu": "09f0a38a-d69e-4f2c-8268-56b530b49e7d",
|
||||
"Intan Jaya": "6b79a9ee-ec93-4c31-a8af-fcff82a005dc",
|
||||
"Jakarta Barat": "8fa110b9-e7c0-427d-95d5-bb7eefd87de9",
|
||||
"Jakarta Pusat": "dc2020ab-0357-491d-a049-9aeda36f0dbf",
|
||||
"Jakarta Selatan": "f224a1ae-844d-41eb-bbcb-58b026f1ed85",
|
||||
"Jakarta Timur": "6e5a2d6e-3519-4f67-9937-3a2a6c63da2c",
|
||||
"Jakarta Utara": "2394e5f6-505f-4056-b4b9-2587a39f3c23",
|
||||
"Jambi": "f9c688ea-95cc-4bec-b9a5-a8bbdac438cc",
|
||||
"Jayapura": "09a4415a-4b1f-4492-92af-dd7d0d2f3051",
|
||||
"Jayawijaya": "3f12fe00-5639-497e-b78a-b8d329b98ed2",
|
||||
"Jember": "762f96d5-5e04-4149-b305-a551dd7f1373",
|
||||
"Jembrana": "c8c4d085-4099-4759-b8cd-7433c5e06082",
|
||||
"Jeneponto": "17152b34-d582-4471-9664-46eb08c38148",
|
||||
"Jepara": "76315b00-9329-48f4-aa19-d1da16d8d7a0",
|
||||
"Jombang": "02e5ae91-c80c-4d85-b236-3e98239cc485",
|
||||
"Kaimana": "08ea2dc7-95a0-4f68-aafe-2bc6a90ea754",
|
||||
"Kampar": "12bdd142-6951-4506-bb6f-971394f8ba9c",
|
||||
"Kapuas": "1bd1f305-14a0-40e1-810e-4f94c7a8f0b8",
|
||||
"Kapuas Hulu": "d1a888f4-dad5-48cd-9282-796e939db95b",
|
||||
"Karanganyar": "7415c883-2187-4aa4-918e-ea6b1b8ec6f1",
|
||||
"Karangasem": "d381faec-1e13-4035-a1f5-63e4752834dd",
|
||||
"Karawang": "e41a0dbb-e7e1-48ea-b7b8-a8e8393f2447",
|
||||
"Karimun": "1add68de-5cf7-4e66-8932-cae53e8e08be",
|
||||
"Karo": "96a7efbc-bdb7-473a-87f2-b56608152a6d",
|
||||
"Katingan": "561dc9e0-5b08-48ce-b464-8b006487e335",
|
||||
"Kaur": "9b45f4c4-367c-4529-9fa3-20d607f618a5",
|
||||
"Kayong Utara": "f5951d28-d7eb-4c8a-9443-bc6daeb2f83a",
|
||||
"Kebumen": "d9fbde43-5c1c-4d63-bc5b-f2a643af8b01",
|
||||
"Kediri": "7a0c8756-2ae2-445f-a7c5-2a05d1cfc283",
|
||||
"Keerom": "c594a25a-e769-4ecb-b7c4-301c6744ff71",
|
||||
"Kendal": "d51acdee-fa4e-42e7-96e0-15cd0cb63a3d",
|
||||
"Kendari": "a1a3ee91-367b-4760-ac1f-e969ad1b4880",
|
||||
"Kepahiang": "6fc59777-c33c-40d0-8097-5bfcb54e7062",
|
||||
"Kepulauan Anambas": "a332812d-0628-4f18-aa99-e93293d6ef82",
|
||||
"Kepulauan Aru": "d0e523d1-94ac-4ca2-b984-4305d27450c7",
|
||||
"Kepulauan Mentawai": "0e219fce-5eda-463d-a7aa-21f8fd705ed9",
|
||||
"Kepulauan Meranti": "4b359324-b946-4d65-9e09-db778e26d3f0",
|
||||
"Kepulauan Sangihe": "4430bf38-628f-4fb0-be27-c6dd4fb83fe6",
|
||||
"Kepulauan Seribu": "0d0906d8-5b25-4fcf-810a-29abdc3fcd8f",
|
||||
"Kepulauan Siau Tagulandang Biaro (Sitaro)": "d14df509-e1eb-40e2-9762-acd3d9c666a8",
|
||||
"Kepulauan Sula": "f28811e8-6b29-4c63-9a07-8c5d61ec9be0",
|
||||
"Kepulauan Talaud": "302f7809-788b-49ea-97e1-994c12090632",
|
||||
"Kepulauan Yapen (Yapen Waropen)": "9b454e6a-09b5-496d-9461-4d2d073eca7d",
|
||||
"Kerinci": "45e1cfdd-ac49-4bb5-9f3a-d51f67851f82",
|
||||
"Ketapang": "a7bb7942-d663-49ae-b766-1e2992a2a9f0",
|
||||
"Klaten": "ea02ebdc-be5b-45d2-86ee-3244c19c4912",
|
||||
"Klungkung": "3c7ababc-09e4-4961-a172-879b00bf8a30",
|
||||
"Kolaka": "ceff0309-8ca5-4aad-99f0-591b46ce7873",
|
||||
"Kolaka Utara": "b37bb2c0-6b29-4423-b81e-d1e61c412b1d",
|
||||
"Konawe": "c79f7afb-b332-43bc-b2a2-991dfd495892",
|
||||
"Konawe Selatan": "53ce17ab-2ad6-49ca-bda5-5a021f2099f6",
|
||||
"Konawe Utara": "cab9d3e0-8052-41c1-9660-ceb2389cd827",
|
||||
"Kotabaru": "a6b553c7-3858-478f-89e4-23e49e6d85ac",
|
||||
"Kotamobagu": "b31df540-37f0-4a4e-9a5e-b0a7c7b4444a",
|
||||
"Kotawaringin Barat": "527f8d3b-cd08-42e7-8e26-76bf43d57c6c",
|
||||
"Kotawaringin Timur": "ee16ff40-a61b-43b1-9364-ca808d755539",
|
||||
"Kuantan Singingi": "08b6895f-b63a-4b28-b3c5-0d7f452eb503",
|
||||
"Kubu Raya": "7d90879d-ef38-4c24-a7c4-17df698906fa",
|
||||
"Kudus": "741058cb-bf21-4879-af6e-e0c8d1379d80",
|
||||
"Kulon Progo": "093e987a-686a-4baf-9a85-8650e5ea9519",
|
||||
"Kuningan": "6b95e261-77b8-45c4-9929-92d5625261d0",
|
||||
"Kupang": "abd05f60-b391-4f02-a56a-6d4e8dd480e1",
|
||||
"Kutai Barat": "81ee3402-7446-4933-b2ef-720431fa9ddc",
|
||||
"Kutai Kartanegara": "3bfcbd09-29b5-4ca0-841d-728c9cf6a02b",
|
||||
"Kutai Timur": "394295c5-504c-455d-b7f3-57a284c3cdf5",
|
||||
"Labuhan Batu": "4d12f877-76cf-48a2-96fc-9f6d5777d292",
|
||||
"Labuhan Batu Selatan": "2174bbc4-ff69-43dc-bdf1-bddd727e97f4",
|
||||
"Labuhan Batu Utara": "0429ec32-ab32-42a9-9415-5246c18ef4a2",
|
||||
"Lahat": "e9f9ba2d-7ef8-47ff-abfd-1bea708279f2",
|
||||
"Lamandau": "9a7fb08f-cc62-4d35-82cc-c378560df8d6",
|
||||
"Lamongan": "1a14b3f0-5b49-4f48-9bd7-8871991b8f6f",
|
||||
"Lampung Barat": "8a625625-b0a8-4a67-8c89-b827293986f4",
|
||||
"Lampung Selatan": "b8c19631-e7e4-496c-83ec-c9215b2dff33",
|
||||
"Lampung Tengah": "a009a9fd-aaba-4ca6-84bc-229f335dd22d",
|
||||
"Lampung Timur": "a6dcdf94-671c-4624-8d22-091a8695c827",
|
||||
"Lampung Utara": "761b51b4-ec82-4458-99e8-74aa66ec22c4",
|
||||
"Landak": "bea71b18-949c-4fd6-8f0e-b39ef3257337",
|
||||
"Langkat": "f64c1370-7237-4503-9791-3db88db84c51",
|
||||
"Langsa": "85cbb31a-4758-4814-ab24-5d1c17a15c4f",
|
||||
"Lanny Jaya": "29a81559-31c6-4428-a63b-9f19f73da510",
|
||||
"Lebak": "8e709aa2-dd47-4f54-bf5e-3563fb36578e",
|
||||
"Lebong": "e8b2311a-4a71-4f76-9daa-ca641e227575",
|
||||
"Lembata": "bd7b52e3-a515-4d4e-97c5-fbde8192d33d",
|
||||
"Lhokseumawe": "b6d96b6b-4434-4879-b160-4c0a2c1cec68",
|
||||
"Lima Puluh Koto/Kota": "402630d1-7210-430b-aaa5-97b0667a109e",
|
||||
"Lingga": "6bb733c2-da0d-4a0f-8026-068239099401",
|
||||
"Lombok Barat": "b0f44161-f153-435c-814c-9a7ee8f00223",
|
||||
"Lombok Tengah": "dcd944b2-8177-4ae7-b946-2cd39eff7bbe",
|
||||
"Lombok Timur": "9a3639b1-aea6-4eb5-8141-756d681be444",
|
||||
"Lombok Utara": "fd173a93-2349-4403-862f-38a6be495706",
|
||||
"Lubuk Linggau": "e223fa2d-197a-44b9-aeb1-41e8c85e3431",
|
||||
"Lumajang": "4f7ba47b-68ae-4c93-892c-c267ba0be25c",
|
||||
"Luwu": "fa5cd790-7b93-41e3-ad89-c91720d9c5a4",
|
||||
"Luwu Timur": "6bdf8e81-23cc-479d-b64d-dfc837c71920",
|
||||
"Luwu Utara": "2634ccc5-91a1-4c71-ae78-58a10c11f42f",
|
||||
"Madiun": "e134dafe-6739-4593-af1c-3a09734a673f",
|
||||
"Magelang": "a55d1ef8-4389-4cd3-ad93-ec304c9e9f9c",
|
||||
"Magetan": "01ecda32-5098-4f2a-a602-b72165ba10cc",
|
||||
"Majalengka": "3e747ac0-7aa6-4002-80bf-495a0376980d",
|
||||
"Majene": "f51ae902-240d-4313-b726-b652820e08af",
|
||||
"Makassar": "10cc22cf-68e1-4d2f-9e7c-95bd63b21dae",
|
||||
"Malang": "691429e6-865e-4bcf-b6b8-81ed3d7e5811",
|
||||
"Malinau": "52914a14-d0cd-4134-bc00-2838d97e62e4",
|
||||
"Maluku Barat Daya": "faead204-d40f-4f9e-a1df-f5f5fd84e19e",
|
||||
"Maluku Tengah": "dd602ed8-2b4c-4495-86ad-8a08ddf9c53d",
|
||||
"Maluku Tenggara": "21bc4d8f-ba0a-4e83-9146-69e4691e6724",
|
||||
"Maluku Tenggara Barat": "80f6a034-60ba-4ae4-b80a-2670e61d54c7",
|
||||
"Mamasa": "5c14efba-3370-469a-a7b5-996f01731033",
|
||||
"Mamberamo Raya": "f3d34226-40ff-4226-99a4-b9080bb0889a",
|
||||
"Mamberamo Tengah": "74a30d89-2110-4a7a-96d8-70d539d287f5",
|
||||
"Mamuju": "e61dffd0-7796-49df-8ba9-dc6d8c0f2782",
|
||||
"Mamuju Utara": "b1623174-63f3-47fd-a051-5d0918f49d12",
|
||||
"Manado": "b7de67d2-a21b-4030-9926-905e7ad05c3f",
|
||||
"Mandailing Natal": "e8554cd5-daff-455d-917f-607af1eae0e2",
|
||||
"Manggarai": "b51637f8-80a3-4581-98ad-7d88a35462f1",
|
||||
"Manggarai Barat": "73aa9e82-c4a0-4527-af21-3e524e2ef944",
|
||||
"Manggarai Timur": "6f57db60-c5d7-4b16-b643-221edcfbd2ff",
|
||||
"Manokwari": "a12dce1d-45d0-479a-8a17-1a5fc8d4da5a",
|
||||
"Manokwari Selatan": "933f358c-1309-4bf9-9f32-901c3383b6f0",
|
||||
"Mappi": "f2a6386b-183d-499e-b08f-84ea1d4eaff8",
|
||||
"Maros": "d745a0b6-a753-4b2a-9222-2ca2d1fdb549",
|
||||
"Mataram": "0687f0ab-902c-4cd4-9cdb-583840906860",
|
||||
"Maybrat": "bd8f5f90-fa69-4c0d-a5dd-7074491c4bdb",
|
||||
"Medan": "3992f782-529a-42d6-bdb2-2a2ca789797d",
|
||||
"Melawi": "5d409df6-1d6d-4180-9798-59cfc4326bdc",
|
||||
"Merangin": "62676a3a-45ff-4ee6-9cac-efa68249aa5a",
|
||||
"Merauke": "5b10d885-7180-441e-9b99-67084a90a770",
|
||||
"Mesuji": "92905f30-1545-4654-ac07-95dc755c297f",
|
||||
"Metro": "e0ce8edd-4217-4e80-b174-5348c1f046f2",
|
||||
"Mimika": "5fc1e479-3b30-4e7a-9d10-954bc1049080",
|
||||
"Minahasa": "a1893432-5b7a-47cc-82b1-2ff5ee38b5b0",
|
||||
"Minahasa Selatan": "1f6540a5-c992-4827-8225-c5e04e2ef0a7",
|
||||
"Minahasa Tenggara": "7c6300a4-7b87-4ae5-aabf-f57585b0eeb6",
|
||||
"Minahasa Utara": "a9e1a951-c986-44ed-89d9-e1f6763b3b6c",
|
||||
"Mojokerto": "4eadc9af-d4eb-49fb-a17e-7ac71848f285",
|
||||
"Morowali": "a67ddbc2-62af-4254-ad29-021cb089682f",
|
||||
"Muara Enim": "d0e626db-a419-4ec2-bdff-3c5b21f391c5",
|
||||
"Muaro Jambi": "e00d99d5-c82a-441e-99ef-7e5f82b6c1d0",
|
||||
"Muko Muko": "d6f1eeab-4ee6-4f2c-83b9-e596a67b0c89",
|
||||
"Muna": "5fdcf0fd-a365-4199-9d64-ee1048e6fb6e",
|
||||
"Murung Raya": "1180ae41-cbf9-4096-976a-b29ccc7ee1d6",
|
||||
"Musi Banyuasin": "26de3842-f08b-4a25-9586-29e74e388cee",
|
||||
"Musi Rawas": "da9bdf53-4392-4d52-b766-469f38bccbc4",
|
||||
"Nabire": "93441661-4f39-419e-a6ac-f93b89fb8df9",
|
||||
"Nagan Raya": "c3885045-240b-489f-8b2d-4986f13dc05b",
|
||||
"Nagekeo": "13783acd-275f-4f67-9030-015c01a18241",
|
||||
"Natuna": "1f2af20f-384e-430c-914c-7b5266ea740a",
|
||||
"Nduga": "961dd0d7-c4ba-4f0c-9f09-a1c0d8e785f0",
|
||||
"Ngada": "7b5ab790-8566-4629-8076-6eba774a77cb",
|
||||
"Nganjuk": "3a4b7db4-c4e7-431b-bbaa-376948d61cc9",
|
||||
"Ngawi": "e0ad2a9f-f4e1-437a-bd5a-3f9d3f0a4cf7",
|
||||
"Nias": "e6bb99c6-3bf6-4050-91d9-ba6846999bad",
|
||||
"Nias Barat": "c05ddc48-d726-45b1-9c86-0aa351952874",
|
||||
"Nias Selatan": "7f2461ae-04b1-40fc-903e-4f47835426a3",
|
||||
"Nias Utara": "d64846f9-e5f8-4723-b7ba-d2560da93614",
|
||||
"Nunukan": "157a075d-952f-434f-911b-dbd8aaee0763",
|
||||
"Ogan Ilir": "2e8b3aea-4b62-48ab-9d38-19a80e7819a9",
|
||||
"Ogan Komering Ilir": "bb080a33-d6b7-48f8-b275-699ec73b67d1",
|
||||
"Ogan Komering Ulu": "8d402a80-ddad-4bfe-b682-ced1c98418c8",
|
||||
"Ogan Komering Ulu Selatan": "5afe5267-c15d-4e09-82d1-891663c1fb02",
|
||||
"Ogan Komering Ulu Timur": "c2c337b8-f9d3-45b0-94c9-d90f4dfd9c54",
|
||||
"Pacitan": "e1e37a05-62c1-4b92-a442-df4848df7db0",
|
||||
"Padang": "d198ff92-cde5-48ed-91de-bea9045311df",
|
||||
"Padang Lawas": "f0a572df-6b81-4b5b-a223-9a3f890d44b8",
|
||||
"Padang Lawas Utara": "700596f1-3de6-4e9e-b5f6-d749f328194a",
|
||||
"Padang Panjang": "1f0be523-f31d-41c3-ae6a-37afcc478424",
|
||||
"Padang Pariaman": "0eafd563-a2c9-4d7a-b9ae-454607db5673",
|
||||
"Padang Sidempuan": "4cb088d6-eeac-4389-9b5b-b1d210dd2e88",
|
||||
"Pagar Alam": "e6cf49a5-f2b3-4ee9-bf44-31bcf475485e",
|
||||
"Pakpak Bharat": "7c8b3e23-a457-4080-ab74-24d22f7ffe8e",
|
||||
"Palangka Raya": "7e2da61c-32a1-413e-b22d-f10374ed6ce5",
|
||||
"Palembang": "a68eea07-56fb-4eea-955b-aac63bfb64f7",
|
||||
"Palopo": "feb44f62-e632-4751-a37b-88e8248f1382",
|
||||
"Palu": "290e759b-c779-4118-b0da-d7c1fadaf51b",
|
||||
"Pamekasan": "2f935621-5bdd-4714-9c48-7b231d92689f",
|
||||
"Pandeglang": "b9314176-95b5-4b60-9d44-a6d870bcba57",
|
||||
"Pangandaran": "cade5c69-f0b9-422a-a30f-26a521371ca1",
|
||||
"Pangkajene Kepulauan": "0d65f465-fabf-4d96-9412-13d5e025e755",
|
||||
"Pangkal Pinang": "4dd00ca1-a314-4636-adb2-06d76dbcf967",
|
||||
"Paniai": "cb0010bd-683e-4026-9433-c78a10aa66c6",
|
||||
"Parepare": "3dd13855-8410-479c-b85e-b6a428e52493",
|
||||
"Pariaman": "f71f8d58-cd38-4d7a-a39a-d9d8bb7ab401",
|
||||
"Parigi Moutong": "bec781f4-a60c-45d8-8597-8d76f8279d08",
|
||||
"Pasaman": "54d78257-8324-4e63-91b2-a3620148f501",
|
||||
"Pasaman Barat": "608548ae-bdae-46fa-a06d-d29fc488b513",
|
||||
"Paser": "53d476a5-6743-4443-aa22-da37d3e62031",
|
||||
"Pasuruan": "65b89ea0-1917-47b3-8109-1eb9e30b622f",
|
||||
"Pati": "70368348-33b2-43b0-bfbf-8ee5e4b4a0f5",
|
||||
"Payakumbuh": "4ba7b2b1-94c0-423f-ac58-bc542ac78f46",
|
||||
"Pegunungan Arfak": "9f3a4a13-b2fe-4df0-a498-32d4efae1d14",
|
||||
"Pegunungan Bintang": "af133659-0e41-44ee-afb5-6d6f7339e14b",
|
||||
"Pekalongan": "14e56c92-0160-49ac-83a9-9158a68d4dd4",
|
||||
"Pekanbaru": "012046d7-83ce-41c4-a655-c96fcc182029",
|
||||
"Pelalawan": "502f398e-fc29-4a7f-a9ec-ec5aee9b0909",
|
||||
"Pemalang": "d812a95e-e09e-4127-a957-b2362e515d63",
|
||||
"Pematang Siantar": "8e806a47-815b-48b3-ad0c-3b56e2b2c3a5",
|
||||
"Penajam Paser Utara": "dac061dd-7b6e-446a-aaf0-c94501f48dfe",
|
||||
"Pesawaran": "a4747228-d44e-4440-add8-84f5d06b23da",
|
||||
"Pesisir Barat": "01bf2b55-517f-46bb-bb15-271c1bdadb19",
|
||||
"Pesisir Selatan": "ddcb23ab-c793-4190-85c7-fc2f4ce55431",
|
||||
"Pidie": "e504f101-088f-4a07-9377-4d78af8acd3d",
|
||||
"Pidie Jaya": "c64de90b-0bd1-4370-a2ee-c6c0955ec5ca",
|
||||
"Pinrang": "31aa36db-3c21-4b6a-9d34-0ecc2e848ee8",
|
||||
"Pohuwato": "4c101057-29f2-4576-9d81-d2ac428330a9",
|
||||
"Polewali Mandar": "58a4d57d-23d0-4401-a843-b29b0dd73b24",
|
||||
"Ponorogo": "5dbba65d-f245-49f8-93df-7ab063271678",
|
||||
"Pontianak": "a45a44b4-a543-4288-bdc8-51c626cf27e7",
|
||||
"Poso": "8d19c38f-6d3e-4f5d-9d57-b61fa839c755",
|
||||
"Prabumulih": "d844ee0b-ee06-45e8-a63e-1ad690cb7ae4",
|
||||
"Pringsewu": "1dd52bd1-2ae8-484a-bd93-f042b6f725b6",
|
||||
"Probolinggo": "161a66c8-b157-4157-98ab-23c4ce03678e",
|
||||
"Pulang Pisau": "7182d77e-f6a3-4b75-8305-7312e35e044c",
|
||||
"Pulau Morotai": "720aad91-3ba1-4941-87d7-5f286a605aad",
|
||||
"Puncak": "3de04717-9877-459b-bd33-04b3260b7400",
|
||||
"Puncak Jaya": "34d7ad7b-8c28-47f4-b430-ccb2c93b198b",
|
||||
"Purbalingga": "86299655-f3b9-4600-b2bf-bfacf793b1c4",
|
||||
"Purwakarta": "6f58468c-f081-43b5-a22e-c5ac07c6d0a8",
|
||||
"Purworejo": "5e2d52ff-6b03-4640-ac7c-5020d8836218",
|
||||
"Raja Ampat": "fafe040b-5300-4898-ba29-8a602203bb91",
|
||||
"Rejang Lebong": "d127ba8c-f4e6-43e6-ba4a-5af7e05fda37",
|
||||
"Rembang": "8d7090f8-b53f-448b-a9ae-56df9545d500",
|
||||
"Rokan Hilir": "23ec296d-ac64-41af-a168-e596f41a34d9",
|
||||
"Rokan Hulu": "89b2dac2-d3a3-4652-8ba5-d82c6688198f",
|
||||
"Rote Ndao": "59a71c44-7029-458f-97eb-93b722fd1939",
|
||||
"Sabang": "7af84996-6e05-4253-924c-bc1e7c99bdc0",
|
||||
"Sabu Raijua": "91095142-2d69-4295-be96-eb330a5982c6",
|
||||
"Salatiga": "a530ab16-ade3-4fb3-b434-2fa9f88468ed",
|
||||
"Samarinda": "867466ae-f45a-474b-9526-3e31137a00b3",
|
||||
"Sambas": "880a715c-c122-403f-9b45-b49d441c4813",
|
||||
"Samosir": "e51b5484-217b-4783-92bc-b1003cd4427f",
|
||||
"Sampang": "2a50d5cf-7557-42bd-9426-e59329c47d9b",
|
||||
"Sanggau": "d26deeeb-cc93-4e2d-8e7c-efd1af143a2f",
|
||||
"Sarmi": "7fd021a5-e5b3-42cd-9058-4ce1a19e1aad",
|
||||
"Sarolangun": "fd057bdd-5c9d-43bb-8678-1fe994c1dbc7",
|
||||
"Sawah Lunto": "996effb6-66f0-4aef-8fec-67cc11e2147a",
|
||||
"Sekadau": "5f3e0ded-087b-472d-bd92-88d860df4435",
|
||||
"Selayar (Kepulauan Selayar)": "96e49ded-55d3-4e8d-841a-d1db4ec43c1c",
|
||||
"Seluma": "33fd9f1f-c94c-4ea6-a1ac-d7c1bf75390f",
|
||||
"Semarang": "a7e4eddb-ad1f-488b-9b0f-07348c840fcd",
|
||||
"Seram Bagian Barat": "e7bbe80d-3e7f-43eb-83ea-95bf5ee5eeee",
|
||||
"Seram Bagian Timur": "e53a856b-17e0-4e7b-b2b0-1ad7e5037f55",
|
||||
"Serang": "8945a9cb-61b0-4910-9f6f-c117125fc37e",
|
||||
"Serdang Bedagai": "a4b220cd-d82d-4cab-84e6-33fdc58ba81e",
|
||||
"Seruyan": "68bf158e-a057-441b-94fe-b95d9a83bf05",
|
||||
"Siak": "ab4ca765-492d-4a84-9bca-7abd1ff513a5",
|
||||
"Sibolga": "5c0ebc5e-044a-4de6-8292-0268bf233fa4",
|
||||
"Sidenreng Rappang/Rapang": "e3345de3-0dcc-4f08-b3ef-ad436ef73039",
|
||||
"Sidoarjo": "730a6d2d-9b11-45d4-a121-462ef6047d90",
|
||||
"Sigi": "2266a183-a093-48ca-ac09-7b14e922fa76",
|
||||
"Sijunjung (Sawah Lunto Sijunjung)": "18bec962-423d-4a95-bd0d-2f85b92d2fe9",
|
||||
"Sikka": "62783bee-c265-47c1-8e7d-c8015d0a72a9",
|
||||
"Simalungun": "c8c711c7-8c5d-4402-ab9e-0ed629b5fdae",
|
||||
"Simeulue": "c5349ec1-acd8-4ea7-b390-c0168cd8dd2b",
|
||||
"Singkawang": "01aad529-a992-4f99-b3d3-198ecb69659a",
|
||||
"Sinjai": "17315423-7d95-4194-a272-510d9a01ceb7",
|
||||
"Sintang": "21a8d2d0-42f7-4469-90c4-85558a2af24c",
|
||||
"Situbondo": "1f189a70-cc19-4532-a9f3-a1d8b0195fbb",
|
||||
"Sleman": "30f30a52-a28c-4981-9943-a6d832697945",
|
||||
"Solok": "f80c6d17-27b4-48a9-8d41-893b46eaee7c",
|
||||
"Solok Selatan": "13be89a2-1276-4019-b285-652da2872e52",
|
||||
"Soppeng": "3cdf07a3-5ccc-4732-8821-2e3949074b5e",
|
||||
"Sorong": "0b301c73-e7b3-4a41-b9d7-08b963f68477",
|
||||
"Sorong Selatan": "f2a57cde-dec2-4b60-a752-ccea008e7325",
|
||||
"Sragen": "38d355d3-2b89-4aa0-91bb-d75f52262a06",
|
||||
"Subang": "a666071e-3e44-4125-b2a8-955134e4197e",
|
||||
"Subulussalam": "8a9a8150-251c-4501-9004-f51c6c32742c",
|
||||
"Sukabumi": "46e58f4b-a4c1-4d3f-b314-72baeb8996f8",
|
||||
"Sukamara": "d4725f47-0a07-4fb9-a70a-06cb67c5f39c",
|
||||
"Sukoharjo": "dd33bd3f-16b5-47cb-8d8b-791eb6248cbe",
|
||||
"Sumba Barat": "f835ed32-a4b6-4941-9f1b-e58e8027bc12",
|
||||
"Sumba Barat Daya": "09450a88-93b0-4525-95f6-ea77684e457f",
|
||||
"Sumba Tengah": "2d0eddf7-5357-48a7-aa1f-8d804c7d3f40",
|
||||
"Sumba Timur": "f9678aab-42f3-4ef5-b499-b88f35d9fcaf",
|
||||
"Sumbawa": "48bc0d15-d379-469d-89b0-b0a50036832c",
|
||||
"Sumbawa Barat": "d48a2fef-81d6-497f-8d0b-a9e559150879",
|
||||
"Sumedang": "d964f615-e39e-4d0d-8e3c-1ebd0d85dfd0",
|
||||
"Sumenep": "eb01eaaa-f337-4fcb-acd4-8237cf7469fe",
|
||||
"Sungaipenuh": "747babf9-eb4e-4822-b70a-7c40b6ef3271",
|
||||
"Supiori": "6240139a-8e6e-4801-9eb0-6469a19a7239",
|
||||
"Surabaya": "e298c2d4-f28d-4087-9075-e1283be22783",
|
||||
"Surakarta (Solo)": "afffed96-8f0f-4033-a132-8c285b5b1c8b",
|
||||
"Tabalong": "26489329-0341-4f3e-a53b-c0997a9d2312",
|
||||
"Tabanan": "9deabf61-4313-40d1-9c0f-3d8483a9f0a3",
|
||||
"Takalar": "64021458-bf82-4bfa-90e4-eb9999535994",
|
||||
"Tambrauw": "c369ecc1-716d-4338-9285-87a2ff70386d",
|
||||
"Tana Tidung": "9d0f25a5-5699-4501-b001-0495322cfebc",
|
||||
"Tana Toraja": "2429940d-f750-465a-818c-ccc0375bb76c",
|
||||
"Tanah Bumbu": "6c805418-866a-48da-9ab5-2a27cda81243",
|
||||
"Tanah Datar": "e97fe0f8-7153-457f-8c17-69ff737bb6f9",
|
||||
"Tanah Laut": "c7a1c97f-d36b-4f14-ad80-4b79c0e1fb8d",
|
||||
"Tangerang": "9ad09297-4043-4312-b7eb-979d70ba0434",
|
||||
"Tangerang Selatan": "994ce06b-5c14-4015-9f88-9da12d0cbb7d",
|
||||
"Tanggamus": "b3a7dd3b-753c-4285-a136-91207055168f",
|
||||
"Tanjung Balai": "fc15f1cd-dc57-4916-983a-f438371a4761",
|
||||
"Tanjung Jabung Barat": "fc641537-e7e9-4285-85ec-187ea4a21754",
|
||||
"Tanjung Jabung Timur": "725d7e5e-461b-4072-b688-020d841d3bde",
|
||||
"Tanjung Pinang": "5b95b0ec-b499-4395-afc6-4a9a3cbf80dc",
|
||||
"Tapanuli Selatan": "e3cce334-1943-47ed-8388-55264cf44a65",
|
||||
"Tapanuli Tengah": "08ffccc0-401e-468a-a9af-6820c0e2d481",
|
||||
"Tapanuli Utara": "3c9a1a7b-4005-4acb-aafd-f469765a4f37",
|
||||
"Tapin": "6918dc94-9a1d-415e-8530-22b4faa83ff7",
|
||||
"Tarakan": "6d71101c-82d9-4d63-8d41-a1a92ed95907",
|
||||
"Tasikmalaya": "26e5c01f-e308-4a90-a4dd-08f6e24e9b67",
|
||||
"Tebing Tinggi": "53d71e98-6039-49ab-82ef-930c050be1ed",
|
||||
"Tebo": "5562a8c6-6ffe-460e-9bb3-4d1ae7a9a8ff",
|
||||
"Tegal": "2d60a8f5-2157-4102-b921-90c84ae8e879",
|
||||
"Teluk Bintuni": "fa1986ba-d517-476e-87ee-fb54f84269e4",
|
||||
"Teluk Wondama": "f1bf4640-70d5-47cf-9ce8-4abb17d34b19",
|
||||
"Temanggung": "a8611c9d-befc-4e8e-817a-9dcac5c4e3e7",
|
||||
"Ternate": "36957898-3926-4fd0-a020-4c4f67a84a63",
|
||||
"Tidore Kepulauan": "cf48d9b9-92a6-4bc5-84bc-bbca52c13939",
|
||||
"Timor Tengah Selatan": "a7553c80-5733-4ce0-9664-b5a9ec08599f",
|
||||
"Timor Tengah Utara": "03fe28c4-2b9c-4e53-89c6-1411ddd41845",
|
||||
"Toba Samosir": "d3e58681-36a5-4c58-b1a1-ec0b0dcaedd5",
|
||||
"Tojo Una-Una": "1c34212d-2d32-4831-891b-84a56e997dc5",
|
||||
"Toli-Toli": "98e3cbaa-66c7-4938-ac24-a428c42251cf",
|
||||
"Tolikara": "313f0f2d-a2f0-4ead-b6c0-17beeb82fc5e",
|
||||
"Tomohon": "995d4405-6770-42b3-9194-199fe5ab9f9f",
|
||||
"Toraja Utara": "2c3f24de-c164-4e59-ba8c-6cb1078b1993",
|
||||
"Trenggalek": "194a92ca-4c8a-4e31-b5ee-2758cc5f83c1",
|
||||
"Tual": "0394d519-ebdf-48d5-8e2c-d417e953d1b2",
|
||||
"Tuban": "aa85479d-1c35-43b6-afe9-d8a764592667",
|
||||
"Tulang Bawang": "06941f50-cc14-4956-b238-972f0f86fa7c",
|
||||
"Tulang Bawang Barat": "a457ef13-730b-44be-8cbe-2ccbe695e90d",
|
||||
"Tulungagung": "d656e583-dcab-43d1-9c39-c82e9195034f",
|
||||
"Wajo": "e85eb0b6-b0b7-4a82-b9cd-d067924b1e53",
|
||||
"Wakatobi": "92ddeae5-0fe2-4034-87cd-e9e71ac4e003",
|
||||
"Waropen": "52288174-17eb-499b-bfb9-07df8d3c3cb5",
|
||||
"Way Kanan": "be237105-ce90-4f0f-9861-3e6a0e8dd041",
|
||||
"Wonogiri": "a2874c97-78e2-4754-87e8-4934e1176dcd",
|
||||
"Wonosobo": "8a271795-da57-40db-a9e8-6cf6ecc67d17",
|
||||
"Yahukimo": "53402e55-1744-41f0-b732-0af19166229b",
|
||||
"Yalimo": "c5fe5a4d-8963-4c67-b266-ce97859400e4",
|
||||
"Yogyakarta": "89e638d9-0c72-4896-8e7d-a85dbe23a88d"
|
||||
}
|
||||
};
|
||||
108
src/common/pages/AcceptInvite/Form.js
Normal file
108
src/common/pages/AcceptInvite/Form.js
Normal file
@@ -0,0 +1,108 @@
|
||||
import React from "react";
|
||||
import {Button, Form, Input, Select} from "antd";
|
||||
const {Option, OptGroup} = Select;
|
||||
const FormItem = Form.Item;
|
||||
|
||||
class ComponentName extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
pass_min_length: 4
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
}
|
||||
|
||||
submit(e) {
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
this
|
||||
.props
|
||||
.form
|
||||
.validateFields((err, value) => {
|
||||
if (err) {
|
||||
return console.error(err);
|
||||
}
|
||||
|
||||
if (this.props.onSubmit && this.props.onSubmit instanceof Function) {
|
||||
this
|
||||
.props
|
||||
.onSubmit(this.props.form, Object.assign({}, value));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onCancel() {
|
||||
// todo, find better way to check if onCancel is a function
|
||||
if (this.props.onCancel && this.props.onCancel instanceof Function) {
|
||||
this
|
||||
.props
|
||||
.onCancel(this.props.form);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const {getFieldDecorator} = this.props.form;
|
||||
|
||||
const emailRule = getFieldDecorator('username', {
|
||||
rules: [
|
||||
{
|
||||
type: 'email',
|
||||
message: 'Email format not valid'
|
||||
}, {
|
||||
required: true,
|
||||
message: 'Please input your email'
|
||||
}
|
||||
],
|
||||
initialValue: this.props.username
|
||||
});
|
||||
|
||||
const passwordRule = getFieldDecorator('password', {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Please input your password'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
return (
|
||||
<Form>
|
||||
<FormItem>
|
||||
{emailRule(
|
||||
<Input className="box-input"
|
||||
placeholder="Email"/>
|
||||
)}
|
||||
</FormItem>
|
||||
|
||||
<FormItem>
|
||||
{passwordRule(
|
||||
<Input className="box-input'"
|
||||
type="password"
|
||||
placeholder="Password"/>
|
||||
)}
|
||||
</FormItem>
|
||||
|
||||
<Button
|
||||
style={{
|
||||
width: "100%",
|
||||
marginBottom: 10
|
||||
}}
|
||||
type="primary"
|
||||
size="large"
|
||||
onClick={() => this.submit()}>
|
||||
Sign in
|
||||
</Button>
|
||||
<p>{this.props.footer}</p>
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default Form.create()(ComponentName);
|
||||
289
src/common/pages/AcceptInvite/index.js
Normal file
289
src/common/pages/AcceptInvite/index.js
Normal file
@@ -0,0 +1,289 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
Paper,
|
||||
Dialog,
|
||||
Card,
|
||||
CardActions,
|
||||
CardHeader,
|
||||
CardMedia,
|
||||
CardTitle,
|
||||
CardText,
|
||||
TextField,
|
||||
FlatButton,
|
||||
Checkbox,
|
||||
RaisedButton,
|
||||
GridList,
|
||||
GridTile,
|
||||
Divider
|
||||
} from 'material-ui';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
|
||||
import './style.scss'
|
||||
import {LINKS} from "../../routes";
|
||||
import {Helmet} from "react-helmet";
|
||||
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class AcceptInvite extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
tokenData: {
|
||||
email: ""
|
||||
},
|
||||
password: "",
|
||||
confirm_password: ""
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.authStore = props.appstate.auth;
|
||||
this.http = props.appstate.http;
|
||||
this.settingStore = props.appstate.setting;
|
||||
}
|
||||
|
||||
handleDialogOpen = (title, message) => {
|
||||
this.setState({
|
||||
dialogTitle: title,
|
||||
dialogMessage: message,
|
||||
openDialog: true
|
||||
})
|
||||
}
|
||||
|
||||
closeDialog = () => {
|
||||
this.setState({
|
||||
openDialog: false
|
||||
})
|
||||
}
|
||||
|
||||
handleTextFieldChange = (event, name) => {
|
||||
this.setState({
|
||||
[name]: event.target.value
|
||||
});
|
||||
};
|
||||
|
||||
acceptInvite() {
|
||||
const {state} = this;
|
||||
if (state.password != '' && state.retype != '') {
|
||||
let contactData = {
|
||||
password: state.password,
|
||||
token: this.query.token,
|
||||
user_id: state.tokenData.id,
|
||||
}
|
||||
|
||||
this.handleDialogOpen('Success', 'Create User Success, Now you can login!');
|
||||
this.props.appstate.http.post('authentication/accept_invite_stores', contactData).then(() => {
|
||||
this.props.history.push(LINKS.LOGIN);
|
||||
})
|
||||
|
||||
// this.authStore.checkUsernameAvaliability(state.username).then(res => {
|
||||
// if (res) {
|
||||
// this.handleDialogOpen('Success', 'Create User Success, Now you can login!');
|
||||
// this.props.appstate.http.post('authentication/accept_invite', contactData).then(() => {
|
||||
// this.props.history.push(LINKS.LOGIN);
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
// )
|
||||
|
||||
// this.handleDialogOpen('Success','Create User Success, Now you can login!');
|
||||
// this.props.appstate.http.post('authentication/accept_invite_admin', contactData).then(() => {
|
||||
// vry.push(LINKS.LOGIN);
|
||||
// })
|
||||
}
|
||||
else {
|
||||
this.handleDialogOpen('Error', 'Please fill all form!');
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.settingStore.getAll();
|
||||
this.query = this
|
||||
.props
|
||||
.location
|
||||
.search
|
||||
.substr(1)
|
||||
.split('&')
|
||||
.reduce((q, value) => {
|
||||
const [k,
|
||||
v] = value.split('=');
|
||||
q[k] = v;
|
||||
return q;
|
||||
}, {});
|
||||
|
||||
if (this.query.token) {
|
||||
this.setState({
|
||||
tokenData: JSON.parse(atob(this.query.token.split('.')[1]))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
handleRetype = (event) => {
|
||||
let password = this.state.password;
|
||||
if (password === event.target.value) {
|
||||
this.setState({
|
||||
error_retype: ''
|
||||
})
|
||||
}
|
||||
else {
|
||||
this.setState({
|
||||
error_retype: 'Password and retype password is not same'
|
||||
})
|
||||
}
|
||||
|
||||
this.setState({
|
||||
retype: event.target.value
|
||||
})
|
||||
};
|
||||
|
||||
render() {
|
||||
const action = [
|
||||
<FlatButton
|
||||
label="Ok"
|
||||
primary={true}
|
||||
onClick={this.closeDialog}
|
||||
style={{marginRight: 10}}
|
||||
/>
|
||||
];
|
||||
// const applicationIcon = (this.settingStore.isIconEmpty) ? "/assets/images/logo_ikan.png" : this.http.appendImagePath(this.settingStore.setting.icon);
|
||||
const applicationIcon = "/assets/images/logo_ikan.png";
|
||||
return (
|
||||
<div className="AcceptInvite">
|
||||
<Helmet>
|
||||
<meta charSet="utf-8"/>
|
||||
<title>Marketplace</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<link rel="icon" type="image/png" href={applicationIcon} sizes="96x96"/>
|
||||
</Helmet>
|
||||
<div style={{width: "100%"}}>
|
||||
{
|
||||
/*(!this.settingStore.setting.name) ?
|
||||
<div style={{textAlign: "center"}}>
|
||||
<Paper style={{
|
||||
backgroundSize: "contain",
|
||||
backgroundClip: "padding-box",
|
||||
padding: 10,
|
||||
height: 75, width: 75,
|
||||
background: '#fff',
|
||||
marginRight: "auto",
|
||||
marginLeft: "auto"
|
||||
}} zDepth={1} circle={true}>
|
||||
<img className="logo" src="/assets/images/logo_ikan.png"/>
|
||||
</Paper>
|
||||
<h2 style={{
|
||||
color: '#275164',
|
||||
marginRight: "auto",
|
||||
marginLeft: "auto",
|
||||
maxWidth: 500,
|
||||
marginTop: 15,
|
||||
marginBottom: 0
|
||||
}}>Marketplace</h2>
|
||||
</div>
|
||||
:
|
||||
<div style={{textAlign: "center"}}>
|
||||
<Paper style={{
|
||||
backgroundSize: "contain",
|
||||
backgroundClip: "padding-box",
|
||||
padding: 10,
|
||||
height: 75, width: 75,
|
||||
background: '#fff',
|
||||
marginRight: "auto",
|
||||
marginLeft: "auto"
|
||||
}} zDepth={1} circle={true}>
|
||||
<img className="logo" src={'/assets/images/logo_ikan.png'}/>
|
||||
</Paper>
|
||||
<h2 style={{
|
||||
color: '#275164',
|
||||
marginRight: "auto",
|
||||
marginLeft: "auto",
|
||||
maxWidth: 500,
|
||||
marginTop: 15,
|
||||
marginBottom: 0
|
||||
}}>{this.settingStore.setting.name}</h2>
|
||||
</div>*/
|
||||
<div style={{textAlign: "center"}}>
|
||||
<Paper style={{
|
||||
backgroundSize: "contain",
|
||||
backgroundClip: "padding-box",
|
||||
padding: 10,
|
||||
height: 75, width: 75,
|
||||
background: '#fff',
|
||||
marginRight: "auto",
|
||||
marginLeft: "auto"
|
||||
}} zDepth={1} circle={true}>
|
||||
<img className="logo" src={'/assets/images/logo_ikan.png'}/>
|
||||
</Paper>
|
||||
<h2 style={{
|
||||
color: '#275164',
|
||||
marginRight: "auto",
|
||||
marginLeft: "auto",
|
||||
maxWidth: 500,
|
||||
marginTop: 15,
|
||||
marginBottom: 0
|
||||
}}>Marketplace</h2>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<Card style={{width: 350, marginTop: '18px'}} className="cardLite">
|
||||
<CardTitle className="align-center" title={<p style={{fontSize: 14}}>New Account Confirmation</p>}>
|
||||
<Divider style={{backgroundColor: '#48d8b2', width: '150px'}} className="margin-auto"/>
|
||||
</CardTitle>
|
||||
|
||||
<form>
|
||||
<CardText>
|
||||
<div className="row">
|
||||
<p className="label-form">Email</p>
|
||||
<TextField
|
||||
hintText="Email"
|
||||
fullWidth={true}
|
||||
name="email"
|
||||
type="email"
|
||||
value={this.state.tokenData.email}
|
||||
disabled={true}
|
||||
/>
|
||||
</div>
|
||||
<div className="row">
|
||||
<p className="label-form">Password</p>
|
||||
<TextField
|
||||
hintText="Password For Login"
|
||||
name="password"
|
||||
fullWidth={true}
|
||||
type="password"
|
||||
value={this.state.password}
|
||||
onChange={(event) => this.handleTextFieldChange(event, 'password')}
|
||||
/>
|
||||
</div>
|
||||
<div className="row">
|
||||
<p className="label-form">Re-Type Password</p>
|
||||
<TextField
|
||||
hintText="Re-Type your Password"
|
||||
name="password"
|
||||
fullWidth={true}
|
||||
type="password"
|
||||
errorText={this.state.error_retype}
|
||||
value={this.state.retype}
|
||||
onChange={this.handleRetype}
|
||||
/>
|
||||
</div>
|
||||
</CardText>
|
||||
<CardActions>
|
||||
<RaisedButton fullWidth={true} primary={true} label="Create your account"
|
||||
onClick={this.acceptInvite.bind(this)}/>
|
||||
</CardActions>
|
||||
</form>
|
||||
</Card>
|
||||
|
||||
<Dialog
|
||||
title={this.state.dialogTitle}
|
||||
actions={action}
|
||||
modal={true}
|
||||
contentStyle={{maxWidth: 350}}
|
||||
open={this.state.openDialog}
|
||||
onRequestClose={() => this.closeDialog()}
|
||||
>
|
||||
{this.state.dialogMessage}
|
||||
</Dialog>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
61
src/common/pages/AcceptInvite/style.scss
Normal file
61
src/common/pages/AcceptInvite/style.scss
Normal file
@@ -0,0 +1,61 @@
|
||||
.AcceptInvite {
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
//background-size: cover;
|
||||
//position: fixed;
|
||||
//height: 100%;
|
||||
//width: 100%;
|
||||
//top:0;
|
||||
//overflow: hidden;
|
||||
.logo {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.background {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background: rgba(128, 0, 128, 0.82); /* fallback for old browsers */
|
||||
background: -webkit-linear-gradient(to top, rgba(0, 204, 187, 0.86), rgba(43, 69, 230, 0.91), rgba(128, 0, 128, 0.92)); /* Chrome 10-25, Safari 5.1-6 */
|
||||
background: linear-gradient(to top, rgba(0, 204, 187, 0.86), rgba(43, 69, 230, 0.91), rgba(128, 0, 128, 0.92));
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
.ant-form-explain {
|
||||
text-align: left;
|
||||
}
|
||||
.login-box {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 460px;
|
||||
height: 320px;
|
||||
padding: 36px;
|
||||
height: 100vh;
|
||||
background-color: #1e2e4a;
|
||||
box-shadow: 0 0 100px rgba(0, 0, 0, .08);
|
||||
.header {
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
margin-bottom: 24px;
|
||||
img {
|
||||
width: 40px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
span {
|
||||
vertical-align: text-bottom;
|
||||
font-size: 16px;
|
||||
text-transform: uppercase;
|
||||
display: inline-block;
|
||||
}
|
||||
p {
|
||||
font-size: 16px;
|
||||
text-transform: uppercase;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
743
src/common/pages/App/index.js
Normal file
743
src/common/pages/App/index.js
Normal file
@@ -0,0 +1,743 @@
|
||||
import React from "react";
|
||||
import {inject, observer} from "mobx-react";
|
||||
import {Link} from "react-router-dom";
|
||||
import {Helmet} from "react-helmet";
|
||||
import "../../styles/constants.scss";
|
||||
import "../../styles/style.scss";
|
||||
import "./style.scss";
|
||||
import {LINKS} from "../../routes";
|
||||
import startcase from "lodash.startcase";
|
||||
import Route from "./routes";
|
||||
import moment from 'moment';
|
||||
import {Icon, Button, Modal, notification} from 'antd';
|
||||
import {
|
||||
Divider,
|
||||
Drawer,
|
||||
List,
|
||||
ListItem,
|
||||
IconMenu,
|
||||
IconButton,
|
||||
MenuItem,
|
||||
DropDownMenu,
|
||||
RaisedButton,
|
||||
Paper,
|
||||
Dialog,
|
||||
Snackbar,
|
||||
Toolbar, ToolbarGroup, ToolbarSeparator, ToolbarTitle, Badge
|
||||
} from 'material-ui';
|
||||
import IconUserCircle from 'material-ui/svg-icons/action/account-circle';
|
||||
import DepositDialog from './../DepositDialog';
|
||||
import WithdrawDialog from './../WithdrawDialog';
|
||||
import IconMenus from 'material-ui/svg-icons/navigation/menu';
|
||||
import LoadingDialog from '../LoadingDialog/index';
|
||||
import * as _ from 'lodash'; // TODO: remove this, import only needed module from lodash
|
||||
import PrintProvider, {Print, NoPrint} from 'react-easy-print';
|
||||
import {black} from "material-ui/styles/colors";
|
||||
import cinnamonSugar from 'cinnamon-sugar';
|
||||
import ButterToast from 'butter-toast';
|
||||
import 'material-design-icons/iconfont/material-icons.css';
|
||||
import {grey400, darkBlack, lightBlack} from 'material-ui/styles/colors';
|
||||
import {getMobileOperatingSystem} from '../../stores/firebase';
|
||||
import Alert from "../../components/Alert";
|
||||
import EmptyComponent from '../EmptyComponent';
|
||||
import NumberFormat from 'react-number-format';
|
||||
|
||||
@inject("appstate")
|
||||
@observer
|
||||
export default class App extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
scriptTawkto: false,
|
||||
redirect: false,
|
||||
open: (window.innerWidth < 600) ? false : true,
|
||||
openSecondary: false,
|
||||
value: '',
|
||||
additionalData: {},
|
||||
valueMultiple: [''],
|
||||
valueSingle: '',
|
||||
visible: false,
|
||||
selectedMenu: this.props.location.pathname,
|
||||
projectId: 'project-id',
|
||||
breadcrumbs: this
|
||||
.props
|
||||
.location
|
||||
.pathname
|
||||
.split('/')
|
||||
.map(path => startcase(path))
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.user = props.appstate.user;
|
||||
this.authStore = props.appstate.auth;
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
this.http = props.appstate.http;
|
||||
this.appstate = props.appstate;
|
||||
this.settingStore = props.appstate.setting;
|
||||
this.transactionStore = props.appstate.transaction;
|
||||
this.dashboardStore = props.appstate.dashboard;
|
||||
this.taskStore = props.appstate.task;
|
||||
this.appStore = props.appstate.app;
|
||||
this.profileStore = props.appstate.profile;
|
||||
this.notificationStore = props.appstate.notification;
|
||||
//
|
||||
// if (getMobileOperatingSystem() !== 'iOS') {
|
||||
// this.messaging = firebase.messaging();
|
||||
// this.notification();
|
||||
// }
|
||||
}
|
||||
|
||||
openNotification(type, title, content, icon) {
|
||||
if (type) {
|
||||
notification[type]({
|
||||
message: (title) ? title : 'Title',
|
||||
description: (content) ? content :
|
||||
<p style={{color: "black"}}>This is the content of the notification. This is the content of the notification.
|
||||
This is the content of the notification.</p>,
|
||||
icon: <Icon type={(icon) ? icon : "smile-circle"} style={{color: 'black'}}/>
|
||||
});
|
||||
notification.open();
|
||||
|
||||
} else {
|
||||
notification.open({
|
||||
message: (title) ? title : 'Title',
|
||||
description: (content) ? <p style={{color: "black"}}>{content}</p> :
|
||||
<p style={{color: "black"}}>This is the content of the notification. This is the content of the notification.
|
||||
This is the content of the notification.</p>,
|
||||
icon: <Icon type={(icon) ? icon : "smile-circle"} style={{color: '#108ee9'}}/>
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
notification = () => {
|
||||
console.log('called again?');
|
||||
this.messaging.onMessage((payload) => {
|
||||
console.log("Message received cok.", payload);
|
||||
// alert(payload.notification.body);
|
||||
const toast = cinnamonSugar({
|
||||
kind: 'crisp',
|
||||
theme: 'info',
|
||||
// picture: 'http://lorempixel.com/150/150/people',
|
||||
title: <a href={payload.notification.click_action}>{payload.notification.title}</a>, // you can also add jsx code here!
|
||||
// message: JSON.stringify(payload), // you can also add jsx code here!
|
||||
message: payload.notification.body, // you can also add jsx code here!
|
||||
toastTimeout: 4000,
|
||||
icon: 'bell' // literally any font awesome 4.7 icon
|
||||
// you may also add here regular butter-toast options, such as toastTimeout,
|
||||
// name, sticky, etc..
|
||||
});
|
||||
ButterToast.raise(toast)
|
||||
});
|
||||
};
|
||||
|
||||
showModal = () => {
|
||||
this.setState({
|
||||
visible: true,
|
||||
});
|
||||
};
|
||||
|
||||
handleOk = (e) => {
|
||||
console.log(e);
|
||||
this.setState({
|
||||
visible: false,
|
||||
});
|
||||
};
|
||||
|
||||
handleCancel = (e) => {
|
||||
console.log(e);
|
||||
this.setState({
|
||||
visible: false,
|
||||
});
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.checkIsLogin();
|
||||
this.settingStore.getAll();
|
||||
this.authStore.getProfile();
|
||||
this.user.getUserGeolocation();
|
||||
this.appStore.getAppType();
|
||||
this.profileStore.getProfile();
|
||||
this.notificationStore.getList()
|
||||
|
||||
notification.config({
|
||||
placement: 'bottomRight',
|
||||
duration: 10,
|
||||
style: {
|
||||
width: 350,
|
||||
color: "black"
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
// will be true
|
||||
const locationChanged = nextProps.location !== this.props.location;
|
||||
|
||||
this.checkIsLogin();
|
||||
}
|
||||
|
||||
checkIsLogin() {
|
||||
// if (!this.authStore.isLoggedIn ) { console.log(this.props.history);
|
||||
// this.props.history.replace(LINKS.LOGIN); }
|
||||
}
|
||||
|
||||
willLogout() {
|
||||
Modal.confirm({
|
||||
title: 'Log out the system?',
|
||||
content: 'Are sure sure you want to log out the system?',
|
||||
okText: 'Confirm',
|
||||
cancelText: 'Cancel',
|
||||
visible: this.state.visible,
|
||||
zIndex: 3000,
|
||||
onOk: () => {
|
||||
this.authStore.logout();
|
||||
this.setState({
|
||||
visible: false,
|
||||
redirect: true
|
||||
});
|
||||
},
|
||||
onCancel: () => {
|
||||
this.setState({
|
||||
visible: false,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
openCreateProjectDialog() {
|
||||
|
||||
}
|
||||
|
||||
handleToggleIcon = () => this.setState({open: !this.state.open});
|
||||
handleToggleIconSecondary = () => this.setState({openSecondary: !this.state.openSecondary});
|
||||
handleClose = () => this.setState({open: false});
|
||||
|
||||
|
||||
handleChangeSingle = (event, value) => {
|
||||
this.setState({
|
||||
valueSingle: value,
|
||||
});
|
||||
};
|
||||
|
||||
handleChangeMultiple = (event, value) => {
|
||||
this.setState({
|
||||
valueMultiple: value,
|
||||
});
|
||||
};
|
||||
|
||||
handleOpenMenu = () => {
|
||||
this.setState({
|
||||
openMenu: true,
|
||||
});
|
||||
}
|
||||
|
||||
handleOnRequestChange = (value) => {
|
||||
this.setState({
|
||||
openMenu: value,
|
||||
});
|
||||
}
|
||||
|
||||
handleChange = (event, index, value) => this.setState({value});
|
||||
|
||||
changeRoute = (path) => {
|
||||
this.setState({selectedMenu: path});
|
||||
if (window.innerWidth < 600) {
|
||||
this.handleClose()
|
||||
}
|
||||
}
|
||||
|
||||
toggle = () => {
|
||||
this.setState({
|
||||
collapsed: !this.state.collapsed
|
||||
});
|
||||
};
|
||||
|
||||
toggleDrawer = () => {
|
||||
this.setState({
|
||||
open: !this.state.open
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
|
||||
const {redirect} = this.state;
|
||||
if (redirect) {
|
||||
this.props.history.replace(LINKS.LOGIN);
|
||||
// return <Redirect to={{
|
||||
// pathname: '/login',
|
||||
// state: {from: this.props.location}
|
||||
// }}/>
|
||||
}
|
||||
const styles = {
|
||||
Paper: {
|
||||
height: 38,
|
||||
width: 38,
|
||||
background: '#fff',
|
||||
marginRight: 16,
|
||||
padding: 4
|
||||
},
|
||||
ImageRounded: {
|
||||
display: 'block',
|
||||
borderRadius: '50%',
|
||||
maxWidth: '100%',
|
||||
marginTop: '0px'
|
||||
}
|
||||
};
|
||||
|
||||
// ROLE dan Menu
|
||||
// agent, ga ada setting, member, task
|
||||
// if (window && !window.Tawk_API) {
|
||||
// const script = document.createElement("script");
|
||||
// (this.settingStore.setting.tawkto_siteid && !this.state.scriptTawkto && this.appstate.userData.role === 'agent') ? (() => {
|
||||
// const scriptText = document.createTextNode(`
|
||||
// var Tawk_API=Tawk_API||{}, Tawk_LoadStart=new Date();
|
||||
// (function(){
|
||||
// var s1=document.createElement("script"),s0=document.getElementsByTagName("script")[0];
|
||||
// s1.async=true;
|
||||
// s1.src='https://embed.tawk.to/${this.settingStore.setting.tawkto_siteid}/default';
|
||||
// s1.charset='UTF-8';
|
||||
// s1.setAttribute('crossorigin','*');
|
||||
// s0.parentNode.insertBefore(s1,s0);
|
||||
// })();`);
|
||||
// script.appendChild(scriptText);
|
||||
// script.async = true;
|
||||
// document.body.appendChild(script);
|
||||
// this.setState({scriptTawkto: true})
|
||||
// })() : '';
|
||||
// }
|
||||
|
||||
const {userData} = this.appstate;
|
||||
// const applicationIcon = (this.settingStore.isIconEmpty) ? "/assets/images/logo_ikan.png" : this.http.appendImagePath(this.settingStore.setting.icon);
|
||||
const applicationIcon = "/assets/images/logo_ikan.png";
|
||||
|
||||
let onNotifRowClick = (record)=>{
|
||||
// if(record.notification.type == 'order_seller' && _.get(record,'notification.additional_data.user_order_store_id',false) != false){
|
||||
// return `${LINKS.ORDER}/${record.notification.additional_data.user_order_store_id}`;
|
||||
// }
|
||||
// else if(record.notification.type == 'order_seller' && _.get(record,'notification.additional_data.user_order_store_id',false) == false){
|
||||
// return `${LINKS.ORDER}`;
|
||||
// }
|
||||
return `${LINKS.ORDER}`;
|
||||
}
|
||||
return (
|
||||
<PrintProvider>
|
||||
<NoPrint>
|
||||
<div className="app-container">
|
||||
<Helmet>
|
||||
<meta charSet="utf-8"/>
|
||||
<title>Marketplace</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<link rel="icon" type="image/png" href={applicationIcon} sizes="96x96"/>
|
||||
</Helmet>
|
||||
|
||||
<ButterToast trayPosition="bottom-right"/>
|
||||
<Snackbar
|
||||
open={this.globalUI.snackbarVisibility}
|
||||
message={this.globalUI.snackbarMessage}
|
||||
autoHideDuration={3000}/>
|
||||
|
||||
{/*<Dialog*/}
|
||||
{/*style={{margin: 'auto'}}*/}
|
||||
{/*open={this.globalUI.loadingVisibility}>*/}
|
||||
{/*<div style={{textAlign: 'center'}}>*/}
|
||||
{/*<LoadingDialog/>*/}
|
||||
{/*</div>*/}
|
||||
{/*</Dialog>*/}
|
||||
<DepositDialog/>
|
||||
<WithdrawDialog/>
|
||||
<Alert></Alert>
|
||||
|
||||
<Toolbar className="toolbarAkunTiket">
|
||||
<ToolbarGroup>
|
||||
<IconButton className="hide-on-med-and-up" onClick={() => this.toggleDrawer()}><IconMenus/></IconButton>
|
||||
<Paper className="show-on-small marketplace-logo" zDepth={1} circle={true}>
|
||||
{
|
||||
// (this.settingStore.isIconEmpty) ?
|
||||
|
||||
// <img style={{width: "100%", height: "100%"}} className=" logo" src="/assets/images/logo_ikan.png"/>
|
||||
// :
|
||||
// <img src={this.http.appendImagePath(this.settingStore.setting.icon)}
|
||||
// style={[styles.ImageRounded, {width: "100%", height: "100%"}]}/>
|
||||
}
|
||||
<img style={{width: "100%", height: "100%"}} className="logo" src={applicationIcon}/>
|
||||
</Paper>
|
||||
|
||||
<ToolbarTitle className="show-on-small marketplace-toolbarTitle" style={{color: '#424770'}}
|
||||
text={"Store Admin"}/>
|
||||
|
||||
<ToolbarSeparator className="hide-on-small-only" style={{marginLeft: 0, marginRight: 10}}/>
|
||||
<IconButton className="hide-on-small-only" style={{marginRight: 10}} onClick={() => this.toggleDrawer()}>
|
||||
<IconMenus/>
|
||||
</IconButton>
|
||||
<Button className="toolbar-button-sysinfo hide-on-small-only" size="small" type="dashed"
|
||||
style={{marginRight: (window.innerWidth < 600) ? 2 : 10}}
|
||||
onClick={() => this.openNotification(null, "System Information", "This is your computer locale timezone", "clock-circle")}>
|
||||
<Icon type="clock-circle"/> <span className="hide-on-small-only">{moment().format('h:mm:ss A')}</span>
|
||||
</Button>
|
||||
{/*<Button className="toolbar-button-sysinfo hide-on-small-only" size="small" type="dashed"*/}
|
||||
{/*style={{marginRight: (window.innerWidth < 600) ? 2 : 10}}*/}
|
||||
{/*onClick={() => this.openNotification(null, "System Information", "This is your computer locale timezone", "environment")}>*/}
|
||||
{/*<Icon type="environment"/><span className="hide-on-small-only">{this.user.userGeolocation.ip}</span>*/}
|
||||
{/*</Button>*/}
|
||||
{/*<Button className="toolbar-button-sysinfo hide-on-small-only" size="small" type="dashed"*/}
|
||||
{/*style={{marginRight: (window.innerWidth < 600) ? 2 : 10}}*/}
|
||||
{/*onClick={() => this.openNotification(null, "System Information", "This is your computer locale timezone", "calendar")}>*/}
|
||||
{/*<Icon type="calendar"/><span className="hide-on-small-only">{this.user.userGeolocation.time_zone}</span>*/}
|
||||
{/*</Button>*/}
|
||||
|
||||
{/*<Button className="toolbar-button-sysinfo hide-on-small-only" size="small" type="dashed"*/}
|
||||
{/*style={{marginRight: (window.innerWidth < 600) ? 2 : 10}}*/}
|
||||
{/*onClick={() => this.openNotification(null, "System Information", "This is your computer locale timezone", "home")}>*/}
|
||||
{/*<Icon type="home"/> <span*/}
|
||||
{/*className="hide-on-small-only">{this.user.userGeolocation.latitude}, {this.user.userGeolocation.longitude}</span>*/}
|
||||
{/*</Button>*/}
|
||||
|
||||
</ToolbarGroup>
|
||||
<ToolbarGroup>
|
||||
<IconMenu
|
||||
anchorOrigin={{vertical: 'bottom', horizontal: 'right'}}
|
||||
targetOrigin={{vertical: 'top', horizontal: 'right'}}
|
||||
onClick={()=>this.notificationStore.readAll()}
|
||||
iconButtonElement={
|
||||
<div>
|
||||
{userData.role === 'admin' ? (
|
||||
<div>
|
||||
{this.notificationStore.unread_notif === 0 ?
|
||||
<IconButton className="menuAkunItem" tooltip="Notification center"
|
||||
tooltipPosition="bottom-center">
|
||||
<img className="img-responsive" src="/assets/images/icon/toa.png" alt=""/>
|
||||
</IconButton> :
|
||||
<Badge
|
||||
badgeContent={this.notificationStore.unread_notif}
|
||||
primary={true}
|
||||
badgeStyle={{top: 15, right: 12}}
|
||||
>
|
||||
<IconButton className="menuAkunItem" tooltip="Notification center"
|
||||
tooltipPosition="bottom-center">
|
||||
<img className="img-responsive" src="/assets/images/icon/toa.png" alt=""/>
|
||||
</IconButton>
|
||||
</Badge>
|
||||
}
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
{this.notificationStore.unread_notif === 0 ?
|
||||
<IconButton className="menuAkunItem" tooltip="Notification center"
|
||||
tooltipPosition="bottom-center">
|
||||
<img className="img-responsive" src="/assets/images/icon/toa.png" alt=""/>
|
||||
</IconButton> :
|
||||
<Badge
|
||||
badgeContent={this.notificationStore.unread_notif}
|
||||
primary={true}
|
||||
badgeStyle={{top: 15, right: 12}}
|
||||
>
|
||||
<IconButton className="menuAkunItem" tooltip="Notification center"
|
||||
tooltipPosition="bottom-center">
|
||||
<img className="img-responsive" src="/assets/images/icon/toa.png" alt=""/>
|
||||
</IconButton>
|
||||
</Badge>
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<List>
|
||||
{
|
||||
(this.notificationStore.list.length) ?
|
||||
this.notificationStore.list.slice(0, 5).map((item, index) => {
|
||||
return (
|
||||
<Link to={onNotifRowClick(item)}>
|
||||
<ListItem
|
||||
// leftAvatar={<Avatar src="images/ok-128.jpg" />}
|
||||
primaryText={item.notification.title}
|
||||
secondaryText={
|
||||
<div>
|
||||
<p>
|
||||
<span style={{color: darkBlack}}>{item.notification.description.substr(0,40)}{(item.notification.description.length > 40) ? '...' : ""}</span>
|
||||
</p>
|
||||
<p style={{fontSize:10,color:black}}>{moment(item.created_at).fromNow()}</p>
|
||||
</div>
|
||||
}
|
||||
secondaryTextLines={2}
|
||||
/>
|
||||
</Link>
|
||||
);
|
||||
}) : <EmptyComponent width="" image="default4" type="empty" header="" content="No notification yet! "/>
|
||||
}
|
||||
<Link to={`${LINKS.INBOX}/notification`}>
|
||||
<ListItem
|
||||
primaryText={
|
||||
<div style={{textAlign:'center'}}>
|
||||
<p>View All</p>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</Link>
|
||||
</List>
|
||||
</IconMenu>
|
||||
|
||||
<IconMenu
|
||||
anchorOrigin={{vertical: 'bottom', horizontal: 'right'}}
|
||||
targetOrigin={{vertical: 'top', horizontal: 'right'}}
|
||||
iconButtonElement={
|
||||
<IconButton style={{width: 'auto', height: 'auto'}} iconStyle={{width: 35, height: 'auto',borderRadius: '45%'}}>
|
||||
{!!this.profileStore.userProfile.photo?
|
||||
<img src={this.http.appendImagePath(this.profileStore.userProfile.photo)}/> : <IconUserCircle/>
|
||||
}
|
||||
|
||||
</IconButton>
|
||||
}
|
||||
><List>
|
||||
<ListItem
|
||||
style={{padding: '0px 16px 0px', fontSize: 14}}
|
||||
disabled={true}
|
||||
primaryText={<span style={{fontWeight: 500}}>{this.authStore.userProfile.username || 'Username'}</span>}
|
||||
secondaryText={<p style={{fontWeight: 400}}>{_.capitalize(this.authStore.userProfile.role) || 'role'}</p>}
|
||||
/>
|
||||
</List>
|
||||
<Divider/>
|
||||
<Link onClick={this
|
||||
.changeRoute
|
||||
.bind(this, '/app/profile')} to={LINKS.PROFILE}> <MenuItem style={{fontSize: 14}}
|
||||
primaryText="Profile"/></Link>
|
||||
<MenuItem onClick={this.willLogout.bind(this)} style={{fontSize: 14}} primaryText="Sign out"/>
|
||||
</IconMenu>
|
||||
</ToolbarGroup>
|
||||
</Toolbar>
|
||||
|
||||
<Drawer containerClassName={(window.innerWidth < 600) ? 'drawer_small' : 'drawer_large transparent no-shadow'}
|
||||
docked={(window.innerWidth < 600) ? false : true}
|
||||
onRequestChange={(open) => this.setState({open})}
|
||||
open={this.state.open}>
|
||||
<Toolbar className="hide-on-med-and-up transparent" style={{marginLeft: 16}}>
|
||||
<ToolbarGroup firstChild={true}>
|
||||
{
|
||||
// (this.settingStore.isIconEmpty) ?
|
||||
|
||||
// <div>
|
||||
// <Paper style={styles.Paper} zDepth={1} circle={true}>
|
||||
// <img style={styles.ImageRounded} className="logo"
|
||||
// src="/assets/images/logo_ikan.png"/>
|
||||
// </Paper>
|
||||
// </div>
|
||||
// :
|
||||
// <div>
|
||||
// <Paper style={styles.Paper} zDepth={1} circle={true}>
|
||||
// <img style={styles.ImageRounded} className="logo"
|
||||
// src={this.http.appendImagePath(this.settingStore.setting.icon)}/>
|
||||
// </Paper>
|
||||
// </div>
|
||||
}
|
||||
<div>
|
||||
<Paper style={styles.Paper} zDepth={1} circle={true}>
|
||||
<img style={styles.ImageRounded} className="logo" src="/assets/images/logo_ikan.png"/>
|
||||
</Paper>
|
||||
</div>
|
||||
{/*<ToolbarTitle style={{color: '#424770'}}
|
||||
text={(this.settingStore.setting.name) ? this.settingStore.setting.name : "Tourmate"}/>*/}
|
||||
<ToolbarTitle style={{color: '#424770'}} text={'Marketplace'}/>
|
||||
</ToolbarGroup>
|
||||
</Toolbar>
|
||||
|
||||
<Link onClick={this
|
||||
.changeRoute
|
||||
.bind(this, '/app/dashboard')} to={LINKS.DASHBOARD}><MenuItem
|
||||
leftIcon={<img src="/assets/images/icon/chart.png"/>}
|
||||
className={(this.state.selectedMenu === '/app/dashboard') ? "menuAkunItem active" : 'menuAkunItem'}><span
|
||||
className="menuAkun">Dashboard</span></MenuItem></Link>
|
||||
|
||||
{
|
||||
userData.role == 'administrator' ?
|
||||
<Link onClick={this
|
||||
.changeRoute
|
||||
.bind(this, '/app/data')} to={LINKS.DATA}> <MenuItem
|
||||
leftIcon={<img src="/assets/images/icon/data.png"/>}
|
||||
className={(this.state.selectedMenu === '/app/data') ? "menuAkunItem active" : 'menuAkunItem'}><span
|
||||
className="menuAkun">Data</span></MenuItem></Link> : ''
|
||||
}
|
||||
|
||||
{
|
||||
userData.role == 'administrator' &&
|
||||
<Link onClick={this
|
||||
.changeRoute
|
||||
.bind(this, '/app/layout')} to={LINKS.LAYOUT}> <MenuItem
|
||||
leftIcon={<img src="/assets/images/icon/layout.png"/>}
|
||||
className={(this.state.selectedMenu === '/app/layout') ? "menuAkunItem active" : 'menuAkunItem'}><span
|
||||
className="menuAkun">Layout</span></MenuItem></Link>
|
||||
}
|
||||
|
||||
{
|
||||
userData.role == 'administrator' &&
|
||||
<Link onClick={this
|
||||
.changeRoute
|
||||
.bind(this, '/app/content')} to={LINKS.CONTENT}> <MenuItem
|
||||
leftIcon={<img src="/assets/images/icon/content.png"/>}
|
||||
className={(this.state.selectedMenu === '/app/content') ? "menuAkunItem active" : 'menuAkunItem'}><span
|
||||
className="menuAkun">Content</span></MenuItem></Link>
|
||||
}
|
||||
|
||||
{
|
||||
userData.role === 'administrator' &&
|
||||
<Link onClick={this
|
||||
.changeRoute
|
||||
.bind(this, '/app/tasks')} to={LINKS.TASKS}> <MenuItem
|
||||
leftIcon={<img src="/assets/images/icon/tasks.png"/>}
|
||||
className={(this.state.selectedMenu === '/app/tasks') ? "menuAkunItem active" : 'menuAkunItem'}><span
|
||||
className="menuAkun">Tasks</span></MenuItem></Link>
|
||||
}
|
||||
|
||||
{
|
||||
userData.role == 'store' ?
|
||||
<Link onClick={this
|
||||
.changeRoute
|
||||
.bind(this, '/app/items')} to={LINKS.ITEMS}> <MenuItem
|
||||
leftIcon={<img src="/assets/images/icon/product.png"/>}
|
||||
className={(this.state.selectedMenu === '/app/items') ? "menuAkunItem active" : 'menuAkunItem'}><span
|
||||
className="menuAkun">Items</span></MenuItem></Link>
|
||||
: ""
|
||||
}
|
||||
|
||||
{
|
||||
userData.role == 'store' ?
|
||||
<Link onClick={this
|
||||
.changeRoute
|
||||
.bind(this, '/app/billing')} to={LINKS.WALLET}> <MenuItem
|
||||
leftIcon={<img src="/assets/images/icon/wallet.png"/>}
|
||||
className={(this.state.selectedMenu === '/app/billing') ? "menuAkunItem active" : 'menuAkunItem'}><span
|
||||
className="menuAkun">Wallet</span></MenuItem></Link> : ""
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
userData.role == 'store' ?
|
||||
<Link onClick={this
|
||||
.changeRoute
|
||||
.bind(this, '/app/orders')} to={LINKS.ORDER}> <MenuItem
|
||||
leftIcon={<img src="/assets/images/icon/accounting.png"/>}
|
||||
className={(this.state.selectedMenu === '/app/orders') ? "menuAkunItem active" : 'menuAkunItem'}><span
|
||||
className="menuAkun">Order</span></MenuItem></Link>
|
||||
: ""
|
||||
}
|
||||
{/*<Link onClick={this*/}
|
||||
{/*.changeRoute*/}
|
||||
{/*.bind(this, '/app/tasks')} to={LINKS.TASKS}> <MenuItem*/}
|
||||
{/*leftIcon={<img src="/assets/images/icon/tasks.png"/>}*/}
|
||||
{/*className={(this.state.selectedMenu === '/app/tasks') ? "menuAkunItem active" : 'menuAkunItem'}><span*/}
|
||||
{/*className="menuAkun">Tasks</span></MenuItem></Link>*/}
|
||||
|
||||
{
|
||||
userData.role == 'store' ?
|
||||
<Link onClick={this
|
||||
.changeRoute
|
||||
.bind(this, '/app/stores')} to={LINKS.STORES}> <MenuItem
|
||||
leftIcon={<img src="/assets/images/icon/store.png"/>}
|
||||
className={(this.state.selectedMenu === '/app/stores') ? "menuAkunItem active" : 'menuAkunItem'}><span
|
||||
className="menuAkun">Store</span></MenuItem></Link> : ''
|
||||
}
|
||||
|
||||
{/* {
|
||||
userData.role == 'store' ?
|
||||
<Link onClick={this
|
||||
.changeRoute
|
||||
.bind(this, '/app/recipes')} to={LINKS.RECIPES}> <MenuItem
|
||||
leftIcon={<img src="/assets/images/icon/recipe.png"/>}
|
||||
className={(this.state.selectedMenu === '/app/recipes') ? "menuAkunItem active" : 'menuAkunItem'}><span
|
||||
className="menuAkun">Recipes</span></MenuItem></Link> : ''
|
||||
} */}
|
||||
|
||||
{/* {
|
||||
userData.role == 'administrator' ?
|
||||
<Link onClick={this
|
||||
.changeRoute
|
||||
.bind(this, '/app/surf_turf')} to={LINKS.SURF}> <MenuItem
|
||||
leftIcon={<img src="/assets/images/icon/grill.png"/>}
|
||||
className={(this.state.selectedMenu === '/app/surf_turf') ? "menuAkunItem active" : 'menuAkunItem'}><span
|
||||
className="menuAkun">Surf & Turf</span></MenuItem></Link> : ''
|
||||
}
|
||||
|
||||
{
|
||||
userData.role == 'administrator' ?
|
||||
<Link onClick={this
|
||||
.changeRoute
|
||||
.bind(this, '/app/help')} to={LINKS.HELP}> <MenuItem
|
||||
leftIcon={<img src="/assets/images/icon/help.png"/>}
|
||||
className={(this.state.selectedMenu === '/app/help') ? "menuAkunItem active" : 'menuAkunItem'}><span
|
||||
className="menuAkun">Help</span></MenuItem></Link> : ''
|
||||
} */}
|
||||
|
||||
|
||||
<Link onClick={this
|
||||
.changeRoute
|
||||
.bind(this, '/app/inbox')} to={LINKS.INBOX}> <MenuItem
|
||||
leftIcon={<img src="/assets/images/icon/inbox.png"/>}
|
||||
className={(this.state.selectedMenu === '/app/inbox') ? "menuAkunItem active" : 'menuAkunItem'}><span
|
||||
className="menuAkun">Inbox</span></MenuItem></Link>
|
||||
{/*{*/}
|
||||
{/*userData.role == 'administrator' && */}
|
||||
<Link onClick={this
|
||||
.changeRoute
|
||||
.bind(this, '/app/setting')} to={LINKS.SETTING}> <MenuItem
|
||||
leftIcon={<img src="/assets/images/icon/settings.png"/>}
|
||||
className={(this.state.selectedMenu === '/app/setting') ? "menuAkunItem active" : 'menuAkunItem'}><span
|
||||
className="menuAkun">Setting</span></MenuItem></Link>
|
||||
{/*}*/}
|
||||
{/*
|
||||
userData.role == 'administrator' ?
|
||||
<Link onClick={this
|
||||
.changeRoute
|
||||
.bind(this, '/app/promotion')} to={LINKS.PROMOTION}> <MenuItem
|
||||
leftIcon={<img src="/assets/images/icon/promotion.png"/>}
|
||||
className={(this.state.selectedMenu === '/app/promotion') ? "menuAkunItem active" : 'menuAkunItem'}><span
|
||||
className="menuAkun">Promotion</span></MenuItem></Link> : ''
|
||||
*/}
|
||||
|
||||
{/*<Link onClick={this*/}
|
||||
{/*.changeRoute*/}
|
||||
{/*.bind(this, '/app/entities')} to={LINKS.ENTITIES}> <MenuItem*/}
|
||||
{/*leftIcon={<img src="/assets/images/icon/walter_white.png"/>}*/}
|
||||
{/*className={(this.state.selectedMenu === '/app/entities') ? "menuAkunItem active" : 'menuAkunItem'}><span*/}
|
||||
{/*className="menuAkun">Entities</span></MenuItem></Link>*/}
|
||||
|
||||
{/*<Link onClick={this*/}
|
||||
{/*.changeRoute*/}
|
||||
{/*.bind(this, '/app/agents')} to={LINKS.AGENT}> <MenuItem*/}
|
||||
{/*leftIcon={<img src="/assets/images/icon/conference.png"/>}*/}
|
||||
{/*className={(this.state.selectedMenu === '/app/agents') ? "menuAkunItem active" : 'menuAkunItem'}><span*/}
|
||||
{/*className="menuAkun">Agents</span></MenuItem></Link>*/}
|
||||
|
||||
{/*<Link onClick={this*/}
|
||||
{/*.changeRoute*/}
|
||||
{/*.bind(this, LINKS.EMPLOYEE)} to={LINKS.EMPLOYEE}> <MenuItem*/}
|
||||
{/*leftIcon={<img src="/assets/images/icon/employee.png"/>}*/}
|
||||
{/*className={(this.state.selectedMenu === LINKS.EMPLOYEE) ? "menuAkunItem active" : 'menuAkunItem'}><span*/}
|
||||
{/*className="menuAkun">Employees</span></MenuItem></Link>*/}
|
||||
|
||||
{/*<Link onClick={this*/}
|
||||
{/*.changeRoute*/}
|
||||
{/*.bind(this, '/app/customers')} to={LINKS.CUSTOMER}> <MenuItem*/}
|
||||
{/*leftIcon={<img src="/assets/images/icon/customer.png"/>}*/}
|
||||
{/*className={(this.state.selectedMenu === '/app/customers') ? "menuAkunItem active" : 'menuAkunItem'}><span*/}
|
||||
{/*className="menuAkun">Customers</span></MenuItem></Link>*/}
|
||||
|
||||
</Drawer>
|
||||
|
||||
<div className="mainContent" style={{
|
||||
paddingLeft: (window.innerWidth < 600) ? '0px' : '50px',
|
||||
marginLeft: (window.innerWidth < 600) ? 'auto' : 'auto',
|
||||
marginRight: (window.innerWidth < 600) ? '0' : 'auto'
|
||||
}}>
|
||||
<div className="try"/>
|
||||
<Route/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</NoPrint>
|
||||
</PrintProvider>
|
||||
);
|
||||
}
|
||||
}
|
||||
130
src/common/pages/App/routes.js
Normal file
130
src/common/pages/App/routes.js
Normal file
@@ -0,0 +1,130 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
Route,
|
||||
Switch
|
||||
} from 'react-router-dom';
|
||||
import {LINKS} from './../../routes'
|
||||
|
||||
import DashboardComponent from './../Dashboard';
|
||||
import ReportComponent from './../Report';
|
||||
import SettingComponent from './../Setting';
|
||||
import WalletComponent from '../Wallet';
|
||||
import ItemsComponent from '../Items/index';
|
||||
import FormItems from "../Items/FormItems/FormItems";
|
||||
import FormItemAdmin from "../Items/FormItems/FormItemAdmin";
|
||||
import FormPromotion from "../Items/FormItems/FormPromotion";
|
||||
import InboxComponent from '../Inbox';
|
||||
import WalletComponentDetail from '../Wallet/Detail';
|
||||
import ProfileComponent from './../Profile';
|
||||
import NotificationAdmin from "../Notification/index";
|
||||
import ServiceComponent from './../Service';
|
||||
import DetailPackage from './../Service/Package/DetailPackage';
|
||||
import StoresComponent from './../Stores';
|
||||
import StoresListComponent from './../StoreList';
|
||||
import UploadItems from "../Items/FormItems/Upload";
|
||||
import UploadPromotion from "../Items/FormItems/UploadPromotion";
|
||||
import UploadAdminDetail from "../Items/FormItems/UploadAdmin";
|
||||
import Tasks from './../Tasks/index';
|
||||
// import TasksDetail from './../Tasks/TaskDetail/index';
|
||||
import CustomerComponent from "../Customers/index";
|
||||
import CustomerDetail from "../CustomerDetail/index";
|
||||
import WalletCostumer from '../CustomerDetail/Wallet/index';
|
||||
import WalletCustomerDetail from '../CustomerDetail/WalletDetail/index';
|
||||
import Categories from "../Categories";
|
||||
import Recipes from "../Recipes";
|
||||
import Help from "../Help";
|
||||
import ContentManager from "../ContentManager";
|
||||
import OrderDetailAirlinesComponent from '../CustomerDetail/OrderDetailAirlines/index';
|
||||
import OrderComponent from './../Order';
|
||||
import OrderDetailComponent from './../Order/OrderDetail/index';
|
||||
import EntitiesComponent from './../Entities/index';
|
||||
import FeaturedItems from '../FeaturedItems/index';
|
||||
import CustomMenus from '../CustomMenus/index';
|
||||
import FeaturedStores from '../FeaturedStores/index';
|
||||
import StoresListDetail from '../StoreList/StoreDetail/index';
|
||||
import FeaturedCategory from "../FeaturedCategory/index";
|
||||
import Promotion from "../Promotion";
|
||||
import FormRecipe from '../Recipes/FormRecipe/index';
|
||||
import FormHelp from '../Help/FormHelp/index';
|
||||
import Form from '../ContentManager/Form/index';
|
||||
import SurfTurf from '../SurfTurf';
|
||||
import SurfForm from '../SurfTurf/form/index';
|
||||
|
||||
import DataTab from '../Data';
|
||||
import LayoutTab from '../Layout';
|
||||
import ContentTab from '../Content';
|
||||
|
||||
export default class ComponentName extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
}
|
||||
|
||||
componentDidMount() {}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Switch>
|
||||
<Route exact component={DashboardComponent} path={LINKS.DASHBOARD}/>
|
||||
<Route exact component={SettingComponent} path={LINKS.SETTING}/>
|
||||
<Route exact component={OrderComponent} path={LINKS.ORDER}/>
|
||||
<Route exact component={WalletComponent} path={LINKS.WALLET}/>
|
||||
<Route exact component={ItemsComponent} path={LINKS.ITEMS}/>
|
||||
<Route exact component={FormItems} path={LINKS.FORM_ITEMS}/>
|
||||
<Route exact component={FormItems} path={LINKS.FORM_ITEMS_EDIT}/>
|
||||
<Route exact component={UploadItems} path={LINKS.FORM_UPLOAD}/>
|
||||
<Route exact component={WalletComponentDetail} path={LINKS.WALLET_DETAIL}/>
|
||||
<Route exact component={WalletCostumer} path={LINKS.WALLET_CUSTOMER}/>
|
||||
<Route exact component={WalletCustomerDetail} path={LINKS.WALLET_CUSTOMER_DETAIL}/>
|
||||
<Route exact component={DetailPackage} path={LINKS.SERVICE_PACKAGE_DETAIL}/>
|
||||
<Route exact component={Tasks} path={LINKS.TASKS}/>
|
||||
{/*<Route exact component={TasksDetail} path={LINKS.TASKS_DETAIL}/>*/}
|
||||
<Route exact component={CustomerComponent} path={LINKS.CUSTOMER} />
|
||||
<Route exact component={Categories} path={LINKS.CATEGORIES} />
|
||||
<Route exact component={Recipes} path={LINKS.RECIPES} />
|
||||
<Route exact component={Help} path={LINKS.HELP} />
|
||||
<Route exact component={ContentManager} path={LINKS.CONTENT_MANAGER} />
|
||||
<Route exact component={NotificationAdmin} path={LINKS.NOTFICATION_ADMIN} />
|
||||
<Route exact component={FeaturedItems} path={LINKS.FEATURED_ITEMS}/>
|
||||
<Route exact component={FeaturedCategory} path={LINKS.FEATURED_CATEGORY}/>
|
||||
<Route exact component={CustomMenus} path={LINKS.CUSTOM_MENU}/>
|
||||
<Route exact component={FeaturedStores} path={LINKS.FEATURED_STORES}/>
|
||||
<Route exact component={StoresListComponent} path={LINKS.STORES_LIST}/>
|
||||
<Route exact component={Promotion} path={LINKS.PROMOTION}/>
|
||||
<Route exact component={FormRecipe} path={LINKS.FORM_RECIPE}/>
|
||||
<Route exact component={FormHelp} path={LINKS.FORM_HELP}/>
|
||||
<Route exact component={Form} path={LINKS.FORM}/>
|
||||
<Route exact component={SurfTurf} path={LINKS.SURF}/>
|
||||
<Route exact component={SurfForm} path={LINKS.FORM_SURF}/>
|
||||
<Route component={SurfForm} path={LINKS.FORM_SURF_EDIT}/>
|
||||
<Route component={FormRecipe} path={LINKS.FORM_RECIPE_EDIT}/>
|
||||
<Route component={FormHelp} path={LINKS.FORM_HELP_EDIT}/>
|
||||
<Route component={Form} path={LINKS.FORM_EDIT}/>
|
||||
<Route component={FormItemAdmin} path={LINKS.FORM_ITEMS_ADMIN}/>
|
||||
<Route component={FormPromotion} path={LINKS.FORM_PROMOTION}/>
|
||||
<Route component={UploadAdminDetail} path={LINKS.FORM_UPLOAD_ADMIN}/>
|
||||
<Route component={UploadPromotion} path={LINKS.FORM_UPLOAD_PROMOTION}/>
|
||||
<Route component={InboxComponent} path={LINKS.INBOX}/>
|
||||
<Route component={InboxComponent} path={LINKS.INBOX+'/:tab'}/>
|
||||
<Route component={DataTab} path={LINKS.DATA}/>
|
||||
<Route component={DataTab} path={LINKS.DATA+'/:tab'}/>
|
||||
<Route component={LayoutTab} path={LINKS.LAYOUT}/>
|
||||
<Route component={LayoutTab} path={LINKS.LAYOUT+'/:tab'}/>
|
||||
<Route component={ContentTab} path={LINKS.CONTENT}/>
|
||||
<Route component={ContentTab} path={LINKS.CONTENT+'/:tab'}/>
|
||||
<Route component={ServiceComponent} path={LINKS.SERVICE}/>
|
||||
<Route component={StoresComponent} path={LINKS.STORES + "/:tab"}/>
|
||||
<Route component={StoresComponent} path={LINKS.STORES}/>
|
||||
<Route component={StoresListDetail} path={LINKS.STORES_LIST_DETAIL}/>
|
||||
<Route component={CustomerDetail} path={LINKS.CUSTOMER_DETAIL} />
|
||||
<Route component={OrderDetailComponent} path={LINKS.ORDER_DETAIL} />
|
||||
<Route component={OrderDetailAirlinesComponent} path={LINKS.ORDER_DETAIL_AIRLINES} />
|
||||
<Route component={ProfileComponent} path={LINKS.PROFILE}/>
|
||||
<Route component={ProfileComponent} path={LINKS.PROFILE + "/:tab"}/>
|
||||
<Route component={EntitiesComponent} path={LINKS.ENTITIES}/>
|
||||
</Switch>
|
||||
)
|
||||
}
|
||||
}
|
||||
129
src/common/pages/App/style.scss
Normal file
129
src/common/pages/App/style.scss
Normal file
@@ -0,0 +1,129 @@
|
||||
.app-container {
|
||||
.mainContent {
|
||||
width: calc(100vw - 275px);
|
||||
position: relative;
|
||||
}
|
||||
@media screen and (max-width: 780px) {
|
||||
.mainContent {
|
||||
width: 100%;
|
||||
}
|
||||
.toolbarAkunTiket {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
z-index: 99;
|
||||
background-color: #f1f5f9 !important;
|
||||
height: 70px !important;
|
||||
padding: 8px 0px !important;
|
||||
border-bottom: 1px solid rgb(223, 223, 223);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.drawer_small {
|
||||
background-color: #fbfbfb !important;
|
||||
box-shadow: 0 7px 14px 0 rgba(50, 50, 93, .1), 0 3px 6px 0 rgba(0, 0, 0, .07) !important;
|
||||
|
||||
}
|
||||
|
||||
.drawer_large {
|
||||
z-index: 10 !important;
|
||||
top: 0;
|
||||
margin-left: 14px;
|
||||
width: 150px !important;
|
||||
padding-top: 76px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.content {
|
||||
margin-top: 16px;
|
||||
padding: 0 50px;
|
||||
}
|
||||
.header-custom {
|
||||
height: 46px;
|
||||
line-height: 46px;
|
||||
}
|
||||
|
||||
.ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.ant-menu-item-selected > a, .ant-menu-item-selected > a:hover {
|
||||
color: #208166;
|
||||
}
|
||||
|
||||
.ant-menu-item > a:hover {
|
||||
color: #208166;
|
||||
}
|
||||
|
||||
.ant-menu-inline .ant-menu-item:after, .ant-menu-vertical .ant-menu-item:after {
|
||||
border-right: 3px solid #208166;
|
||||
}
|
||||
|
||||
#components-layout-demo-custom-trigger .ant-layout-sider-collapsed .ant-row-flex.menu-toolbar-flex {
|
||||
width: 84vw;
|
||||
|
||||
}
|
||||
|
||||
.menuAkun {
|
||||
font-size: 13px !important;
|
||||
font-weight: 500 !important;
|
||||
color: #424770 !important;
|
||||
margin-left: -20px !important;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.toolbarAkunTiket {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
z-index: 1100;
|
||||
background-color: #f1f5f9 !important;
|
||||
height: 70px !important;
|
||||
padding: 8px 24px;
|
||||
border-bottom: 1px solid rgb(223, 223, 223);
|
||||
}
|
||||
|
||||
.avatar-with-text {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
|
||||
}
|
||||
|
||||
.menuAkunItem {
|
||||
transition: all 0.2s ease !important;
|
||||
}
|
||||
|
||||
.menuAkunItem:hover {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.menuAkunItem:hover span.menuAkun {
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
|
||||
.menuAkunItem img {
|
||||
|
||||
filter: grayscale(90%);
|
||||
}
|
||||
|
||||
.menuAkunItem:hover img {
|
||||
filter: grayscale(0%);
|
||||
}
|
||||
|
||||
.menuAkunItem.active img {
|
||||
filter: grayscale(0%);
|
||||
}
|
||||
|
||||
.menuAkunItem.active span.menuAkun {
|
||||
font-weight: 600 !important;
|
||||
color: #28489a;
|
||||
}
|
||||
|
||||
.menuAkun {
|
||||
letter-spacing: 0.03em;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
51
src/common/pages/Breadcrumb/index.js
Normal file
51
src/common/pages/Breadcrumb/index.js
Normal file
@@ -0,0 +1,51 @@
|
||||
import React from 'react';
|
||||
import {inject, observer} from 'mobx-react';
|
||||
import {Router, Route, browserHistory} from 'react-router';
|
||||
import {Breadcrumb, Alert} from 'antd';
|
||||
import {LINKS} from "../../routes";
|
||||
import {HashRouter, Link} from 'react-router-dom';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class BreadcrumbComponent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
console.log(this.props.history, "breadcumb")
|
||||
}
|
||||
|
||||
render() {
|
||||
const Apps = () => (
|
||||
<ul className="app-list">
|
||||
<li>
|
||||
<Link to="/apps/1">Application1</Link>:<Link to="/apps/1/detail">Detail</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to="/apps/2">Application2</Link>:<Link to="/apps/2/detail">Detail</Link>
|
||||
</li>
|
||||
</ul>
|
||||
);
|
||||
|
||||
const Home = ({routes, params, children}) => (
|
||||
<div className="demo">
|
||||
<div className="demo-nav">
|
||||
<Link to="/">Home</Link>
|
||||
<Link to="/apps">Application List</Link>
|
||||
</div>
|
||||
{children || 'Home Page'}
|
||||
<Alert style={{margin: '16px 0'}} message="Click the navigation above to switch:"/>
|
||||
<Breadcrumb routes={routes} params={params} linkRender="" nameRender=""/>
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div className="breadcrumb">
|
||||
{/*<Home/>*/}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
313
src/common/pages/Categories/Dialog/CategoryData.js
Normal file
313
src/common/pages/Categories/Dialog/CategoryData.js
Normal file
@@ -0,0 +1,313 @@
|
||||
import React from 'react';
|
||||
import {inject, observer} from 'mobx-react';
|
||||
import {DatePicker, MenuItem, SelectField, TextField, Checkbox, } from 'material-ui';
|
||||
import { Upload, Icon, Modal, Input, Select, Switch, message, Button as ButtonAntd } from 'antd';
|
||||
import schema from 'async-validator'
|
||||
import startCase from 'lodash.startcase';
|
||||
import moment from 'moment';
|
||||
import get from 'lodash.get';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class CategoryData extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
formData: Object.assign({
|
||||
name : '',
|
||||
icon : '',
|
||||
background_image : ''
|
||||
},props.defaultValue ) || {},
|
||||
checked: true,
|
||||
errorText: {},
|
||||
onChangeTimeoutId: false,
|
||||
countries: [],
|
||||
previewVisible : '',
|
||||
previewImage : '',
|
||||
fileList : '',
|
||||
previewVisibleBackground : '',
|
||||
previewImageBackground : '',
|
||||
fileListBackground : ''
|
||||
};
|
||||
|
||||
this.http = props.appstate.http;
|
||||
}
|
||||
|
||||
// componentWillUnmount(){
|
||||
|
||||
// }
|
||||
|
||||
componentDidMount() {
|
||||
const {defaultValue={}} = this.props;
|
||||
|
||||
this.setState({
|
||||
formData : {
|
||||
...this.state.formData,
|
||||
...defaultValue
|
||||
}
|
||||
})
|
||||
|
||||
if(defaultValue.image){
|
||||
if(defaultValue.image.background_image != ""){
|
||||
let file = defaultValue.image.background_image.split("/");
|
||||
this.setState({
|
||||
fileListBackground : [{
|
||||
uid: file[2],
|
||||
name: file[2],
|
||||
status: 'done',
|
||||
url: this.http.appendImagePath(defaultValue.image.background_image),
|
||||
path: defaultValue.image.background_image,
|
||||
type: 'main'
|
||||
}]
|
||||
})
|
||||
}
|
||||
|
||||
if(defaultValue.image.icon != ""){
|
||||
let file = defaultValue.image.icon.split("/");
|
||||
this.setState({
|
||||
fileList : [{
|
||||
uid: file[2],
|
||||
name: file[2],
|
||||
status: 'done',
|
||||
url: this.http.appendImagePath(defaultValue.image.icon),
|
||||
path: defaultValue.image.icon,
|
||||
type: 'main'
|
||||
}]
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
handleCancelBackground = () => this.setState({ previewVisibleBackground: false });
|
||||
handleChangeBackground = ({ fileList }) => {
|
||||
this.setState({ fileListBackground : fileList });
|
||||
console.log(fileList, 'remove')
|
||||
if(fileList.length == 0){
|
||||
this.setState({
|
||||
formData : {
|
||||
...this.state.formData,
|
||||
background_image : ''
|
||||
}
|
||||
},()=>this.triggerOnChange(2))
|
||||
}
|
||||
};
|
||||
|
||||
uploaderHandlerBackground({file, onProgress}) {
|
||||
this.http.upload(file)
|
||||
.then(res => {
|
||||
const {fileListBackground} = this.state;
|
||||
let newFileList = fileListBackground.filter((obj)=>{
|
||||
if(!obj.lastModified){
|
||||
return true;
|
||||
}
|
||||
|
||||
})
|
||||
newFileList.push({
|
||||
uid: newFileList.length,
|
||||
name: file.name,
|
||||
status: 'done',
|
||||
url: this.http.appendImagePath(res.path),
|
||||
path: res.path,
|
||||
type: 'main'
|
||||
});
|
||||
|
||||
this.setState({
|
||||
fileListBackground : newFileList,
|
||||
formData : {
|
||||
...this.state.formData,
|
||||
background_image : res.path
|
||||
}
|
||||
}, () => this.triggerOnChange(2));
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
handleCancel = () => this.setState({ previewVisible: false });
|
||||
handleChange = ({ fileList }) => {
|
||||
this.setState({ fileList });
|
||||
console.log(fileList, 'remove')
|
||||
if(fileList.length == 0){
|
||||
this.setState({
|
||||
formData : {
|
||||
...this.state.formData,
|
||||
icon : ''
|
||||
}
|
||||
},()=>this.triggerOnChange(2))
|
||||
}
|
||||
};
|
||||
uploaderHandlerIcon({file, onProgress}) {
|
||||
this.http.upload(file)
|
||||
.then(res => {
|
||||
const {fileList} = this.state;
|
||||
let newFileList = fileList.filter((obj)=>{
|
||||
if(!obj.lastModified){
|
||||
return true;
|
||||
}
|
||||
|
||||
})
|
||||
newFileList.push({
|
||||
uid: newFileList.length,
|
||||
name: file.name,
|
||||
status: 'done',
|
||||
url: this.http.appendImagePath(res.path),
|
||||
path: res.path,
|
||||
type: 'main'
|
||||
});
|
||||
this.setState({
|
||||
fileList : newFileList,
|
||||
formData : {
|
||||
...this.state.formData,
|
||||
icon : res.path
|
||||
}
|
||||
}, () => this.triggerOnChange(2));
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
triggerOnChange(key) {
|
||||
this.props.onChangeData(this.state.formData);
|
||||
// if (this.state.onChangeTimeoutId) {
|
||||
// this.setState({
|
||||
// onChangeTimeoutId: false
|
||||
// });
|
||||
// return clearTimeout(this.state.onChangeTimeoutId);
|
||||
// }
|
||||
|
||||
// const onChangeTimeoutId = setTimeout(() => {
|
||||
// if (this.props.onChangeData && typeof this.props.onChangeData === 'function') {
|
||||
// this.props.onChangeData(this.state.formData);
|
||||
// }
|
||||
|
||||
// this.setState({
|
||||
// onChangeTimeoutId: false
|
||||
// });
|
||||
|
||||
// }, 322);
|
||||
|
||||
// this.setState({onChangeTimeoutId});
|
||||
}
|
||||
|
||||
updateCheck() {
|
||||
this.setState((oldState) => {
|
||||
return {
|
||||
checked: !oldState.checked,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { previewVisible, previewImage, fileList,previewVisibleBackground, previewImageBackground, fileListBackground } = this.state;
|
||||
|
||||
const uploadButton = (
|
||||
<div>
|
||||
<Icon type="plus" />
|
||||
<div className="ant-upload-text">Upload</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
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 {mode="create"} = this.props;
|
||||
|
||||
return(
|
||||
<div style={{
|
||||
paddingTop: 10
|
||||
}}>
|
||||
|
||||
<div className="row">
|
||||
|
||||
<div className="col s12 m12 l12">
|
||||
<div>
|
||||
<p className="label-form">Name</p>
|
||||
{wrapperText("name")(
|
||||
<TextField
|
||||
fullWidth={true}
|
||||
hintText="E.g. Sport"/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Icon</p>
|
||||
<Upload
|
||||
listType="picture-card"
|
||||
fileList={fileList}
|
||||
customRequest={(...args) => this.uploaderHandlerIcon(...args)}
|
||||
style={{}}
|
||||
onChange={this.handleChange}
|
||||
>
|
||||
{fileList.length == 1 ? null : uploadButton}
|
||||
</Upload>
|
||||
<Modal visible={previewVisible} footer={null} onCancel={this.handleCancel}>
|
||||
<img alt="example" style={{ width: '100%' }} src={previewImage} />
|
||||
</Modal>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form" onClick={()=>console.log(this.state.formData)}>Background Image</p>
|
||||
<Upload
|
||||
listType="picture-card"
|
||||
fileList={fileListBackground}
|
||||
customRequest={(...args) => this.uploaderHandlerBackground(...args)}
|
||||
style={{}}
|
||||
onChange={this.handleChangeBackground}
|
||||
>
|
||||
{fileListBackground.length == 1 ? null : uploadButton}
|
||||
</Upload>
|
||||
<Modal visible={previewVisibleBackground} footer={null} onCancel={this.handleCancelBackground}>
|
||||
<img alt="example" style={{ width: '100%' }} src={previewImageBackground} />
|
||||
</Modal>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
263
src/common/pages/Categories/Dialog/index.js
Normal file
263
src/common/pages/Categories/Dialog/index.js
Normal file
@@ -0,0 +1,263 @@
|
||||
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 CategoriesDialog extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
stepIndex: 0,
|
||||
formData: {},
|
||||
finished: false,
|
||||
openedDialog: false,
|
||||
formData: {},
|
||||
errorMessage: ''
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
this.customer = props.appstate.customer;
|
||||
|
||||
this.categoriesStore = props.appstate.category;
|
||||
}
|
||||
|
||||
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 input the name'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const validator = new schema(rules);
|
||||
|
||||
validator.validate(this.state.formData, (errs, f) => {
|
||||
console.log(errs);
|
||||
if (errs) {
|
||||
this.globalUI.showNotification("Something's Wrong", errs[0].message);
|
||||
} else {
|
||||
this.setState({
|
||||
stepIndex: stepIndex + 1,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
handlePrev = () => {
|
||||
const {stepIndex} = this.state;
|
||||
if (stepIndex > 0) {
|
||||
this.setState({stepIndex: stepIndex - 1});
|
||||
}
|
||||
}
|
||||
|
||||
handleClose = () => {
|
||||
this.setState({confirmationDialog: false})
|
||||
};
|
||||
|
||||
save = () => {
|
||||
this.globalUI.hideDialog(DIALOG.SETTING.CATEGORIES);
|
||||
this.globalUI.showDialogLoading();
|
||||
const {mode="create", defaultValue={}} = this.props;
|
||||
|
||||
if (mode === "create") {
|
||||
let data = this.state.formData;
|
||||
data.image = {
|
||||
icon : this.state.formData.icon,
|
||||
background_image : this.state.formData.background_image
|
||||
}
|
||||
delete data.icon;
|
||||
delete data.background_image;
|
||||
this.categoriesStore.postCategory(data)
|
||||
.then(res => {
|
||||
this.globalUI.hideDialogLoading();
|
||||
this.globalUI.openSnackbar("Success Added New Category");
|
||||
this.setState({
|
||||
stepIndex: 0
|
||||
})
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
} else if (mode === "update") {
|
||||
let data = this.state.formData;
|
||||
data.image = {
|
||||
icon : this.state.formData.icon,
|
||||
background_image : this.state.formData.background_image
|
||||
}
|
||||
delete data.icon;
|
||||
delete data.background_image;
|
||||
this.categoriesStore.putCategory(defaultValue.id, data)
|
||||
.then(res => {
|
||||
// this.globalUI.hideDialog(DIALOG.EMPLOYEE.CREATE);
|
||||
this.globalUI.hideDialogLoading();
|
||||
this.globalUI.openSnackbar("Success Updated Category")
|
||||
this.setState({
|
||||
stepIndex: 0
|
||||
})
|
||||
// this.categoriesStore.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 New" : "Update"} Category</h4>
|
||||
</div>
|
||||
;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Dialog
|
||||
title={<div>
|
||||
<div>{title}</div>
|
||||
<div style={{padding: "0px 14px 0px 0px", marginTop: 10}}>
|
||||
<Stepper activeStep={stepIndex}>
|
||||
<Step>
|
||||
<StepLabel style={{padding: "0px 14px 0px 0px", height: 52}}>Category 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.globalUI.hideDialog(DIALOG.SETTING.CATEGORIES) : this.handlePrev()}
|
||||
/>
|
||||
{this.continueButton()}
|
||||
</div>}
|
||||
autoScrollBodyContent={true}
|
||||
repositionOnUpdate={true}
|
||||
open={this.globalUI[DIALOG.SETTING.CATEGORIES]}
|
||||
onRequestClose={this.handleClose}
|
||||
style={{zIndex: 999}}
|
||||
>
|
||||
<div style={{marginTop: 20}}>
|
||||
{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>
|
||||
)
|
||||
}
|
||||
}
|
||||
261
src/common/pages/Categories/index.js
Normal file
261
src/common/pages/Categories/index.js
Normal file
@@ -0,0 +1,261 @@
|
||||
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 ImageEdit from 'material-ui/svg-icons/image/edit';
|
||||
import EmptyComponent from '../EmptyComponent';
|
||||
import LoadingDialog from "../LoadingDialog";
|
||||
import Loader from 'react-loader-advanced';
|
||||
import {appConfig} from "../../config/app";
|
||||
import {Link} from 'react-router-dom';
|
||||
import {LINKS} from "../../routes";
|
||||
import moment from 'moment';
|
||||
import {DIALOG} from "../../stores/global_ui";
|
||||
import DialogCreate from './Dialog';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class Categories extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
value: 0,
|
||||
edit : false,
|
||||
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.categoryStore = props.appstate.category;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.globalUI.openLoading();
|
||||
this.categoryStore.getCategoryList().then(res => {
|
||||
this.globalUI.closeLoading();
|
||||
});
|
||||
}
|
||||
|
||||
handleUpdateInput = (searchText) => {
|
||||
this.setState({
|
||||
searchText: searchText,
|
||||
});
|
||||
};
|
||||
|
||||
handleNewRequest = () => {
|
||||
this.setState({
|
||||
searchText: '',
|
||||
});
|
||||
};
|
||||
|
||||
tabsHandleChange = (value) => {
|
||||
this.setState({
|
||||
slideIndex: value,
|
||||
});
|
||||
};
|
||||
|
||||
deleteClicked = (id) => {
|
||||
this.setState({
|
||||
id : id,
|
||||
openedDelete: true
|
||||
});
|
||||
}
|
||||
|
||||
editData = (index)=>{
|
||||
|
||||
// console.log(index);
|
||||
this.setState({
|
||||
edit : true,
|
||||
defaultValue : this.categoryStore.categoryList[index]
|
||||
},()=>{
|
||||
this.globalUI.showDialog(DIALOG.SETTING.CATEGORIES);
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
handleOpenDialog = () => {
|
||||
this.setState({
|
||||
edit : false
|
||||
})
|
||||
this.globalUI.showDialog(DIALOG.SETTING.CATEGORIES);
|
||||
}
|
||||
|
||||
handleClickDelete = (id) => {
|
||||
this.categoryStore.deleteCategory(id).then(res=>{
|
||||
this.setState({
|
||||
openedDelete: false,
|
||||
openSnackbarDelete: true
|
||||
});
|
||||
this.globalUI.openSnackbar("Successful Deleted Existing Category");
|
||||
|
||||
}).catch(err=>{
|
||||
console.log(err);
|
||||
this.globalUI.openSnackbar("Something Wrong :(");
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
handleCloseDelete = () => {
|
||||
this.setState({
|
||||
openedDelete: false
|
||||
})
|
||||
}
|
||||
|
||||
handleChange = (event, index, value) => this.setState({value});
|
||||
|
||||
search = (event)=>{
|
||||
if(event.target.value.length == 0){
|
||||
this.categoryStore.isSearching = false;
|
||||
}
|
||||
else{
|
||||
this.categoryStore.isSearching = true;
|
||||
this.categoryStore.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 Category"
|
||||
style={{fontSize: 14}}
|
||||
hintStyle={{fontSize: 14}}
|
||||
underlineShow={false}
|
||||
onChange={this.search}
|
||||
/>
|
||||
</ToolbarGroup>
|
||||
<ToolbarGroup className="ToolbarGroupLast">
|
||||
<ToolbarSeparator/>
|
||||
<RaisedButton className="ToolbarGroupLastButton" icon={<AddIcon/>} label="New Category"
|
||||
primary={true} onClick={this.handleOpenDialog}/>
|
||||
</ToolbarGroup>
|
||||
</Toolbar>
|
||||
<Divider/>
|
||||
<div style={{paddingBottom: 5}}>
|
||||
<Loader show={this.globalUI.loadingVisibility} message={<LoadingDialog/>}
|
||||
messageStyle={{textAlign: 'center'}} backgroundStyle={{backgroundColor: 'rgba(255,255,255,0.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'}}>ID</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun" style={{height: 'auto'}}>Created At</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto', textAlign: 'right'}}>Action</TableHeaderColumn>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody displayRowCheckbox={false}>
|
||||
|
||||
{(!this.categoryStore.isCategoryEmpty) ? (this.categoryStore.isSearching ? this.categoryStore.dataFiltered : this.categoryStore.categoryList).map((item, index) => {
|
||||
return (
|
||||
<TableRow key={item.id}>
|
||||
<TableRowColumn>
|
||||
<div style={{color : '#6772e5',cursor : 'pointer'}} onClick={()=>this.editData(index)}>
|
||||
{item.name}
|
||||
</div>
|
||||
</TableRowColumn>
|
||||
<TableRowColumn>{moment(item.created_at).format('DD MMMM YYYY, HH:mm:ss')}</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>
|
||||
</Loader>
|
||||
</div>
|
||||
<Dialog
|
||||
title="Warning"
|
||||
actions={actionsDelete}
|
||||
modal={true}
|
||||
open={this.state.openedDelete}
|
||||
onRequestClose={() => this.handleCloseDelete()}
|
||||
>
|
||||
Are you sure want to delete this data?
|
||||
</Dialog>
|
||||
{this.state.edit ? <DialogCreate mode="update" defaultValue={Object.assign({},this.state.defaultValue)}/> : <DialogCreate mode="create"/>}
|
||||
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
221
src/common/pages/ChangePassword/index.js
Normal file
221
src/common/pages/ChangePassword/index.js
Normal file
@@ -0,0 +1,221 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
Paper,
|
||||
Dialog,
|
||||
Card,
|
||||
CardActions,
|
||||
CardHeader,
|
||||
CardMedia,
|
||||
CardTitle,
|
||||
CardText,
|
||||
TextField,
|
||||
FlatButton,
|
||||
Checkbox,
|
||||
RaisedButton,
|
||||
GridList,
|
||||
GridTile,
|
||||
Divider
|
||||
} from 'material-ui';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import LoadingDialog from '../LoadingDialog/index';
|
||||
import {LINKS} from "../../routes";
|
||||
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class ChangePassword extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
password : '',
|
||||
error_retype : '',
|
||||
retype : '',
|
||||
loading : false,
|
||||
tokenData : {
|
||||
email : ""
|
||||
},
|
||||
status : 0,
|
||||
openDialog : false
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.authStore = props.appstate.auth;
|
||||
this.http = props.appstate.http;
|
||||
}
|
||||
|
||||
|
||||
handleTextFieldChange = (event, name) => {
|
||||
this.setState({
|
||||
[name]: event.target.value
|
||||
});
|
||||
};
|
||||
|
||||
handleDialogOpen = (title,message)=>{
|
||||
this.setState({
|
||||
dialogTitle : title,
|
||||
dialogMessage : message,
|
||||
openDialog : true
|
||||
})
|
||||
}
|
||||
|
||||
acceptInvite() {
|
||||
const {state} = this;
|
||||
if(state.username != '' && state.password != '' && state.retype != ''){
|
||||
this.setState({loading : true})
|
||||
let contactData = {
|
||||
password : state.password,
|
||||
id : state.tokenData.id,
|
||||
}
|
||||
this.handleDialogOpen('Success','Change Password Success');
|
||||
this.http.post('authentication/reset_password',contactData).then(res=>{
|
||||
this.setState({loading : false,status : 1});
|
||||
this.handleDialogOpen('Success','Success change password');
|
||||
}).catch(err=>{
|
||||
this.setState({loading : false,status : 0});
|
||||
this.handleDialogOpen('Error','Something went wrong');
|
||||
})
|
||||
// this.props.appstate.http.post('authentication/accept_invite_admin', contactData).then(() => {
|
||||
// })
|
||||
}
|
||||
else{
|
||||
this.handleDialogOpen('Error','Please fill all form!');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
componentDidMount() {
|
||||
this.query = this
|
||||
.props
|
||||
.location
|
||||
.search
|
||||
.substr(1)
|
||||
.split('&')
|
||||
.reduce((q, value) => {
|
||||
const [k,
|
||||
v] = value.split('=');
|
||||
q[k] = v;
|
||||
return q;
|
||||
}, {});
|
||||
|
||||
if(this.query.token) {
|
||||
this.setState({
|
||||
tokenData: JSON.parse(atob(this.query.token.split('.')[1]))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
handleRetype = (event)=>{
|
||||
let password = this.state.password;
|
||||
if(password === event.target.value){
|
||||
this.setState({
|
||||
error_retype : ''
|
||||
})
|
||||
}
|
||||
else{
|
||||
this.setState({
|
||||
error_retype : 'Password and retype password is not same'
|
||||
})
|
||||
}
|
||||
|
||||
this.setState({
|
||||
retype : event.target.value
|
||||
})
|
||||
};
|
||||
|
||||
closeDialog = ()=>{
|
||||
if(this.state.status){
|
||||
this.props.history.push(LINKS.LOGIN);
|
||||
}
|
||||
else{
|
||||
this.setState({
|
||||
openDialog : false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const action = [
|
||||
<FlatButton
|
||||
label="Ok"
|
||||
primary={true}
|
||||
onClick={()=>this.closeDialog()}
|
||||
style={{marginRight: 10}}
|
||||
/>
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="AcceptInvite">
|
||||
<img className="logo" src="/assets/images/logo_ikan.png" style={{maxWidth : '200px'}}/>
|
||||
<h1 style={{color:'#275164'}}>5 Roti dan 2 Ikan</h1>
|
||||
<h4 style={{color:'#55dab6'}}>Marketplace</h4>
|
||||
<Card style={{width:450, marginTop:'18px'}} className="cardLite">
|
||||
<CardTitle className="align-center" title={<p style={{fontSize:14}}>Confirm Password</p>}>
|
||||
<Divider style={{backgroundColor:'#48d8b2', width:'150px'}} className="margin-auto"/>
|
||||
</CardTitle>
|
||||
|
||||
<CardText>
|
||||
<div className="row">
|
||||
<p className="label-form">Email</p>
|
||||
<TextField
|
||||
hintText="Email"
|
||||
fullWidth={true}
|
||||
name="email"
|
||||
type="email"
|
||||
value={this.state.tokenData.email}
|
||||
disabled={true}
|
||||
/>
|
||||
</div>
|
||||
<div className="row">
|
||||
<p className="label-form">Password</p>
|
||||
<TextField
|
||||
hintText="Password"
|
||||
name="password"
|
||||
fullWidth={true}
|
||||
type="password"
|
||||
value={this.state.password}
|
||||
onChange={(event) => this.handleTextFieldChange(event, 'password')}
|
||||
/>
|
||||
</div>
|
||||
<div className="row">
|
||||
<p className="label-form">Re-Type Password</p>
|
||||
<TextField
|
||||
hintText="Re-Type your Password"
|
||||
name="password"
|
||||
fullWidth={true}
|
||||
type="password"
|
||||
errorText={this.state.error_retype}
|
||||
value={this.state.retype}
|
||||
onChange={this.handleRetype}
|
||||
/>
|
||||
</div>
|
||||
</CardText>
|
||||
<CardActions>
|
||||
<RaisedButton fullWidth={true} primary={true} label="Change password" onClick={() => this.acceptInvite()}/>
|
||||
</CardActions>
|
||||
</Card>
|
||||
|
||||
<Dialog
|
||||
title={this.state.dialogTitle}
|
||||
actions={action}
|
||||
modal={true}
|
||||
contentStyle={{maxWidth: 350}}
|
||||
open={this.state.openDialog}
|
||||
onRequestClose={() => this.setState({openDialog : false})}
|
||||
>
|
||||
{this.state.dialogMessage}
|
||||
</Dialog>
|
||||
<Dialog
|
||||
open={this.state.loading}
|
||||
contentStyle={{maxWidth: 350}}
|
||||
modal={true}
|
||||
>
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<LoadingDialog/>
|
||||
</div>
|
||||
</Dialog>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
87
src/common/pages/Content/index.js
Normal file
87
src/common/pages/Content/index.js
Normal file
@@ -0,0 +1,87 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import {
|
||||
Tabs, Tab,
|
||||
} from 'material-ui';
|
||||
import {LINKS} from "../../routes";
|
||||
import '../Inbox/style.scss';
|
||||
import ContentManagement from '../ContentManager';
|
||||
|
||||
export const TABS_LIST = {
|
||||
POSTS: 'posts',
|
||||
TAGS: 'tags',
|
||||
};
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class ContentTabComponent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.taskStore = props.appstate.task;
|
||||
this.state = {
|
||||
tabSelected: TABS_LIST.POSTS,
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.http = props.appstate.http;
|
||||
this.authStore = props.appstate.auth;
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// this.props.history.push(LINKS.INBOX +`/${this.messageStore.selectedTab}`)
|
||||
let activeTab = (this.globalUI.contentTabSelected ? this.globalUI.contentTabSelected : TABS_LIST.POSTS);
|
||||
this.setState({
|
||||
tabSelected : activeTab
|
||||
});
|
||||
this.props.history.push(LINKS.CONTENT +`/${activeTab}`)
|
||||
}
|
||||
|
||||
handleChange = (tabSelected) => {
|
||||
this.setState({
|
||||
tabSelected: tabSelected,
|
||||
});
|
||||
this.globalUI.contentTabSelected = tabSelected;
|
||||
this.props.history.push(LINKS.CONTENT+'/'+tabSelected);
|
||||
};
|
||||
|
||||
getContent() {
|
||||
switch (this.state.tabSelected) {
|
||||
case TABS_LIST.POSTS:
|
||||
return <ContentManagement history={this.props.history}/>
|
||||
case TABS_LIST.TAGS:
|
||||
return <div>2</div>
|
||||
default:
|
||||
return <div>3</div>
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
<div className="inbox containerMiddle">
|
||||
<div className="row no-margin">
|
||||
<div className="col l12 m12 s12">
|
||||
<Tabs
|
||||
value={this.state.tabSelected}
|
||||
onChange={this.handleChange}
|
||||
inkBarStyle={{background: 'transparent'}}
|
||||
className="tabsAkun"
|
||||
style={{background: 'transparent'}}
|
||||
>
|
||||
<Tab label="Posts" value="posts"
|
||||
className={(this.state.tabSelected === 'posts') ? "buttonTabs buttonTabsActive" : 'buttonTabs'}>
|
||||
</Tab>
|
||||
{/*<Tab label="Tags" value="tags"*/}
|
||||
{/*className={(this.state.tabSelected === 'tags') ? "buttonTabs buttonTabsActive" : 'buttonTabs'}>*/}
|
||||
{/*</Tab>*/}
|
||||
|
||||
</Tabs>
|
||||
|
||||
{this.getContent()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
733
src/common/pages/ContentManager/Form/index.js
Normal file
733
src/common/pages/ContentManager/Form/index.js
Normal file
@@ -0,0 +1,733 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import {
|
||||
Card,
|
||||
FlatButton,
|
||||
Divider,
|
||||
RaisedButton,
|
||||
Toolbar,
|
||||
MenuItem,
|
||||
ToolbarGroup,
|
||||
IconButton,
|
||||
ToolbarTitle,
|
||||
Dialog,
|
||||
Toggle
|
||||
} from 'material-ui';
|
||||
import DeleteIcon from 'material-ui/svg-icons/action/delete';
|
||||
import {Icon, Input, Select, message, Button as ButtonAntd, Affix,TreeSelect} from 'antd'
|
||||
import {LINKS} from "../../../routes";
|
||||
const Option = Select.Option;
|
||||
const TreeNode = TreeSelect.TreeNode;
|
||||
import {lowerCase,debounce} from 'lodash';
|
||||
|
||||
// Require Editor JS files.
|
||||
// import 'froala-editor/js/froala_editor.pkgd.min.js';
|
||||
// Require Editor CSS files.
|
||||
// import 'froala-editor/css/froala_style.min.css';
|
||||
// import 'froala-editor/css/froala_editor.pkgd.min.css';
|
||||
const $ = require("jquery");
|
||||
require("froala-editor/js/froala_editor.pkgd.min.js")($);
|
||||
window.$ = window.jQuery = $;
|
||||
// require("froala-editor/js/froala_editor.pkgd.min.js")($);
|
||||
// require("froala-editor/js/plugins/code_view.min.js")($);
|
||||
// window.$ = window.jQuery = $;
|
||||
import 'froala-editor/css/froala_style.min.css';
|
||||
import 'froala-editor/css/froala_editor.pkgd.min.css';
|
||||
// import 'froala-editor/css/plugins/code_view.min.css';
|
||||
// Require Font Awesome.
|
||||
import 'font-awesome/css/font-awesome.css';
|
||||
|
||||
import FroalaEditor from 'react-froala-wysiwyg';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class Form extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.rewardStore = props.appstate.reward;
|
||||
this.state = {
|
||||
openedDialogEmpty:false,
|
||||
featured_media_exist: false,
|
||||
text: '',
|
||||
openedDialog: false,
|
||||
openDeleteDialog : false,
|
||||
saveButton: true,
|
||||
value: 1,
|
||||
isFree : false,
|
||||
searchText: '',
|
||||
slideIndex: 0,
|
||||
openedDialogBack: false,
|
||||
reward_type: "Choose Reward Type",
|
||||
expanded: false,
|
||||
previewVisible: false,
|
||||
previewImage: '',
|
||||
fileList: [],
|
||||
fileLength: 0,
|
||||
fileMainExist: false,
|
||||
visible:false,
|
||||
formData: {
|
||||
//tags: ['a571f41f-c9d2-4fe1-9638-320c589cffe3'],
|
||||
tags: [],
|
||||
additional_data : {
|
||||
items: []
|
||||
}
|
||||
},
|
||||
disabled_price : false,
|
||||
mode: 'create',
|
||||
html : "",
|
||||
config: {
|
||||
placeholderText: 'Edit Your Content Here!',
|
||||
charCounterCount: true,
|
||||
toolbarStickyOffset: 73,
|
||||
toolbarButtons: ['insertLink', 'bold', 'italic', 'underline', 'fontFamily', 'fontSize', 'color', 'align', 'formatOL', 'formatUL', 'embedly', '|', 'insertImage', 'insertVideo', 'insertFile', '|', 'help'],
|
||||
quickInsertButtons: ['embedly','hr', 'image', 'video'],
|
||||
codeBeautifierOptions: {
|
||||
end_with_newline: true,
|
||||
indent_inner_html: true,
|
||||
extra_liners: "['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'pre', 'ul', 'ol', 'table', 'dl']",
|
||||
brace_style: 'expand',
|
||||
indent_char: ' ',
|
||||
indent_size: 4,
|
||||
wrap_line_length: 0
|
||||
},
|
||||
heightMin: '50vh'
|
||||
}
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.http = props.appstate.http;
|
||||
this.authStore = props.appstate.auth;
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
this.categoryStore = props.appstate.category;
|
||||
this.itemStore = props.appstate.item;
|
||||
this.myStoreItem = props.appstate.myStoreItem;
|
||||
this.contentManagerStore = props.appstate.contentManager;
|
||||
this.editor = null;
|
||||
this.userData = props.appstate.userData;
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
console.log(this.props.match.params.id,'ini id params')
|
||||
window.scrollTo(0, 0);
|
||||
|
||||
this.contentManagerStore.getTags();
|
||||
// this.contentManagerStore.getTypes();
|
||||
this.contentManagerStore.clearItems();
|
||||
if(this.props.match.params.id){
|
||||
this.contentManagerStore.getDetail(this.props.match.params.id).then(res => {
|
||||
console.log(this.contentManagerStore.selected.title,this.contentManagerStore.selected.content,'res detail')
|
||||
|
||||
let newArray = this.contentManagerStore.selected.additional_data.items.map(it => it);
|
||||
let newTagsArray =this.contentManagerStore.selected.tags.map(it => it);
|
||||
|
||||
console.log(newTagsArray[0].tag_id,'newTagsArray');
|
||||
if(newArray.length>0){
|
||||
this.contentManagerStore.loadItems(newArray);
|
||||
}
|
||||
|
||||
let data;
|
||||
data = {
|
||||
title:this.contentManagerStore.selected.title,
|
||||
type:this.contentManagerStore.selected.type,
|
||||
content:this.contentManagerStore.selected.content,
|
||||
tags:[newTagsArray[0].tag_id],
|
||||
additional_data:{
|
||||
items: newArray
|
||||
}
|
||||
}
|
||||
|
||||
this.setState({
|
||||
formData : data,
|
||||
text : this.contentManagerStore.selected.content,
|
||||
});
|
||||
|
||||
if(newTagsArray[0].tag_id == 'b0819754-fb35-4e52-be67-eb76ca80c5a4'){
|
||||
this.setState({
|
||||
visible:true
|
||||
})
|
||||
}
|
||||
// console.log("new formmm",this.state.formData,this.state.text)
|
||||
|
||||
});
|
||||
|
||||
// console.log("new formmm items",this.state.formData.additional_data.items)
|
||||
}
|
||||
|
||||
// $('.fr-wrapper').children[0].style.display = 'none';
|
||||
// setTimeout(() => {
|
||||
// $('.fr-wrapper').children[0].style.display = 'none';
|
||||
// }, 1000);
|
||||
|
||||
}
|
||||
|
||||
handleModelChange = (model) => {
|
||||
this.setState({
|
||||
text: model
|
||||
});
|
||||
};
|
||||
|
||||
handleCancel = () => this.setState({ previewVisible: false });
|
||||
|
||||
|
||||
handleOpen = () => {
|
||||
console.log(this.state.html,'heree');
|
||||
this.setState({openedDialog: true});
|
||||
};
|
||||
|
||||
handleClose = () => {
|
||||
this.setState({openedDialog: false});
|
||||
};
|
||||
|
||||
goToClassDetail(){
|
||||
this.props.history.push(`${LINKS.CLASSES}/${this.props.match.params.id}`);
|
||||
}
|
||||
|
||||
postData = () => {
|
||||
console.log("post!!!", this.state.formData);
|
||||
if(!this.state.formData.title || this.state.formData.title=="" || !this.state.text || this.state.text==""){
|
||||
message.success('Title and content cannot be empty!');
|
||||
console.log('inikosongdatanya')
|
||||
this.setState({openedDialog: false});
|
||||
this.setState({openedDialogEmpty:true});
|
||||
}
|
||||
else{
|
||||
this.setState({openedDialog: false});
|
||||
this.globalUI.openLoading();
|
||||
const data=Object.assign({},this.state.formData);
|
||||
data.content=this.state.text;
|
||||
// if(typeof data.price === "string"){
|
||||
// data.price = new DC(data.price.replace(/\,/g,"")).toFixed();
|
||||
// }
|
||||
|
||||
console.log("data",data);
|
||||
this.contentManagerStore.post(data)
|
||||
.then(res => {
|
||||
this.globalUI.hideDialogLoading();
|
||||
this.globalUI.openSnackbar("Success Added New Content");
|
||||
this.props.history.push(LINKS.CONTENT);
|
||||
})
|
||||
.catch(err => {
|
||||
this.globalUI.openSnackbar(err.message);
|
||||
console.error(err, 'ini errornya');
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
deleteData = () => {
|
||||
|
||||
};
|
||||
|
||||
searchItem = ()=>{
|
||||
console.log('do search');
|
||||
};
|
||||
|
||||
editData = () => {
|
||||
console.log("Edit!!!", this.state.formData);
|
||||
if(!this.state.formData.title || this.state.formData.title=="" || !this.state.text || this.state.text==""){
|
||||
console.log('inikosongdatanya')
|
||||
this.setState({openedDialog: false});
|
||||
this.setState({openedDialogEmpty:true});
|
||||
}
|
||||
else{
|
||||
this.globalUI.openLoading();
|
||||
this.setState({openedDialog: false});
|
||||
const data=Object.assign({},this.state.formData);
|
||||
data.content=this.state.text;
|
||||
console.log("data",data);
|
||||
this.contentManagerStore.put(this.props.match.params.id,data)
|
||||
.then(res => {
|
||||
this.globalUI.hideDialogLoading();
|
||||
this.globalUI.openSnackbar("Success Edit Content");
|
||||
this.props.history.push(LINKS.CONTENT_MANAGER);
|
||||
})
|
||||
.catch(err => {
|
||||
this.globalUI.openSnackbar(err.message);
|
||||
console.error(err, 'ini errornya');
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
handleBackClose = () => {
|
||||
this.setState({openedDialogBack: false})
|
||||
};
|
||||
|
||||
handleEmptyClose = () => {
|
||||
this.setState({openedDialogEmpty: false})
|
||||
};
|
||||
|
||||
handleEmptyOpen = () => {
|
||||
this.setState({openedDialogEmpty: true})
|
||||
};
|
||||
|
||||
handleBackOpen = () => {
|
||||
this.setState({openedDialogBack: true});
|
||||
};
|
||||
|
||||
inputContent = (evt)=>{
|
||||
// console.log(evt.target.value);
|
||||
this.setState({
|
||||
html : evt.target.value
|
||||
})
|
||||
}
|
||||
|
||||
handleChange = ({ fileList }) => {this.setState({ fileList }); console.log(fileList, 'remove')};
|
||||
|
||||
uploaderHandler({file, onProgress}) {
|
||||
console.log(file, 'upload');
|
||||
console.log("fileLength", this.state.fileLength);
|
||||
console.log("fileMainExist", this.state.fileMainExist);
|
||||
this.http.upload(file)
|
||||
.then(res => {
|
||||
const {fileList} = this.state;
|
||||
let newFileList = fileList.filter((obj)=>{
|
||||
if(!obj.lastModified){
|
||||
return true;
|
||||
}
|
||||
|
||||
})
|
||||
if(!this.state.fileMainExist){
|
||||
newFileList.push({
|
||||
uid: newFileList.length,
|
||||
name: file.name,
|
||||
status: 'done',
|
||||
url: this.http.appendImagePath(res.path),
|
||||
path: res.path,
|
||||
type: 'main'
|
||||
});
|
||||
}
|
||||
else{
|
||||
newFileList.push({
|
||||
uid: newFileList.length,
|
||||
name: file.name,
|
||||
status: 'done',
|
||||
url: this.http.appendImagePath(res.path),
|
||||
path: res.path,
|
||||
type: 'gallery'
|
||||
});
|
||||
}
|
||||
|
||||
console.log("update fileList",fileList);
|
||||
console.log("new fileList",newFileList);
|
||||
this.setState({fileList : newFileList});
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
handleWarningDialog = (bool)=>{
|
||||
this.setState({
|
||||
openDeleteDialog : bool
|
||||
})
|
||||
}
|
||||
|
||||
setFree = (bool) =>{
|
||||
this.setState({
|
||||
formData : {
|
||||
...this.state.formData,
|
||||
is_free: bool,
|
||||
price : 0
|
||||
},
|
||||
disabled_price : bool
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
//add mock data for tag option, change this if api for tag is complete
|
||||
const children = [];
|
||||
for (let i = 10; i < 36; i++) {
|
||||
children.push(<Option key={i.toString(36) + i}>{i.toString(36) + i}</Option>);
|
||||
}
|
||||
|
||||
const { previewVisible, previewImage, fileList } = this.state;
|
||||
|
||||
const uploadButton = (
|
||||
<div>
|
||||
<Icon type="plus" />
|
||||
<div className="ant-upload-text">Upload</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const actions = [
|
||||
<FlatButton
|
||||
label="Cancel"
|
||||
primary={true}
|
||||
style={{marginRight: 10}}
|
||||
onClick={this.handleClose}
|
||||
/>,
|
||||
<RaisedButton
|
||||
label={this.props.match.params.id ? "Edit" : "Publish"}
|
||||
primary={true}
|
||||
disabled={this.itemStore.isLoading}
|
||||
onClick={this.props.match.params.id ? this.editData : this.postData}
|
||||
/>,
|
||||
];
|
||||
|
||||
const actionsDelete = [
|
||||
<FlatButton
|
||||
label="Cancel"
|
||||
primary={true}
|
||||
style={{marginRight: 10}}
|
||||
onClick={()=>this.handleWarningDialog(false)}
|
||||
/>,
|
||||
<RaisedButton
|
||||
label={"Delete"}
|
||||
primary={true}
|
||||
disabled={this.itemStore.isLoading}
|
||||
onClick={this.deleteData}
|
||||
/>,
|
||||
];
|
||||
|
||||
const actionsBack = [
|
||||
<FlatButton
|
||||
label="No"
|
||||
primary={true}
|
||||
style={{marginRight: 10}}
|
||||
onClick={this.handleBackClose}
|
||||
/>,
|
||||
<RaisedButton
|
||||
label="Yes"
|
||||
primary={true}
|
||||
onClick={() => this.props.history.goBack()}
|
||||
/>,
|
||||
];
|
||||
|
||||
const actionsEmpty = [
|
||||
<RaisedButton
|
||||
label="Yes"
|
||||
primary={true}
|
||||
onClick={this.handleEmptyClose}
|
||||
/>,
|
||||
];
|
||||
|
||||
const wrapperText = key => ele => React.cloneElement(ele, {
|
||||
value: this.state.formData[key],
|
||||
onChange: (e) => {
|
||||
let data = e.target.value
|
||||
this.setState({
|
||||
formData: {
|
||||
...this.state.formData,
|
||||
[key]: data
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const wrapperSelect = key => ele => React.cloneElement(ele, {
|
||||
value: this.state.formData[key],
|
||||
onChange: (e, k, v) => {
|
||||
this.setState({
|
||||
formData: {
|
||||
...this.state.formData,
|
||||
[key]: [e],
|
||||
}
|
||||
}, () => {
|
||||
if(e == 'b0819754-fb35-4e52-be67-eb76ca80c5a4'){
|
||||
this.setState({
|
||||
visible:true
|
||||
})
|
||||
}
|
||||
else{
|
||||
this.contentManagerStore.clearItems();
|
||||
this.setState({
|
||||
visible:false
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const wrapperSelectType = key => ele => React.cloneElement(ele, {
|
||||
value: this.state.formData[key],
|
||||
onChange: (e, k, v) => {
|
||||
this.setState({
|
||||
formData: {
|
||||
...this.state.formData,
|
||||
[key]: e,
|
||||
}
|
||||
}, () => {
|
||||
console.log('value',this.state.formData[key])
|
||||
console.log('value2',e)
|
||||
console.log("Key",key)
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const wrapperSelectANT = key => ele => React.cloneElement(ele, {
|
||||
value: this.state.formData.additional_data[key],
|
||||
// errorText: this.state.errorText[key],
|
||||
onChange: (v) => {
|
||||
this.setState({
|
||||
formData: {
|
||||
...this.state.formData,
|
||||
additional_data:{
|
||||
[key] : v
|
||||
}
|
||||
}
|
||||
}, () => {
|
||||
console.log("value",this.state.formData.additional_data[key]);
|
||||
|
||||
console.log("value2",v);
|
||||
console.log("key",key);
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const wrapperTree = key => ele => React.cloneElement(ele, {
|
||||
value: this.state.formData.additional_data[key],
|
||||
// errorText: this.state.errorText[key],
|
||||
onChange: (v) => {
|
||||
this.setState({
|
||||
formData: {
|
||||
...this.state.formData,
|
||||
additional_data:{
|
||||
[key] : v
|
||||
}
|
||||
}
|
||||
}, () => {
|
||||
console.log("value",this.state.formData.additional_data[key]);
|
||||
this.contentManagerStore.itemChange(v);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return (
|
||||
|
||||
<div style={{marginTop: 35}}>
|
||||
<div className="row">
|
||||
<div className="col s12">
|
||||
<Card className="animated fadeIn cardLite" style={{marginLeft: 12, marginRight: 12}}>
|
||||
<Toolbar className="toolbarCard" style={{backgroundColor: '#fff'}}>
|
||||
<ToolbarGroup>
|
||||
<IconButton
|
||||
iconClassName="material-icons"
|
||||
tooltip="Back"
|
||||
style={{marginLeft: '-10px'}}
|
||||
onClick={this.handleBackOpen}
|
||||
>
|
||||
arrow_back
|
||||
</IconButton>
|
||||
<ToolbarTitle style={{fontSize: 14, fontWeight: 500, color: '#32325d'}} text={this.props.match.params.id ? 'Edit Content' : 'Create Content'}/>
|
||||
</ToolbarGroup>
|
||||
<ToolbarGroup>
|
||||
{!(this.state.mode == 'create') ? <RaisedButton onClick={()=>this.handleWarningDialog(true)} icon={<DeleteIcon/>} label="Delete" primary={true} style={{marginRight : '1px'}}/> : ''}
|
||||
{/*!(this.state.mode == 'update') ? <RaisedButton icon={<SaveIcon/>} label="Save as draft" primary={true} style={{marginRight : '1px'}}/> : ''*/}
|
||||
</ToolbarGroup>
|
||||
</Toolbar>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
<div className={"row"}>
|
||||
<div className={"col s12"}>
|
||||
<div className="row">
|
||||
<div className={"col s9"}>
|
||||
<Card className="animated fadeIn cardLite">
|
||||
<FroalaEditor
|
||||
model={this.state.text}
|
||||
config={this.state.config}
|
||||
onModelChange={this.handleModelChange}
|
||||
onManualControllerReady={(initControls) => {
|
||||
console.log(initControls, 'initControls initControls');
|
||||
initControls.initialize();
|
||||
this.editor = initControls.getEditor();
|
||||
this.editor().on('froalaEditor.image.beforeUpload', (e, editor, files) => {
|
||||
if (files.length) {
|
||||
let name = files[0].name;
|
||||
this.props.appstate.http.upload(files[0]).then(it => {
|
||||
editor.image.insert(this.http.appendImagePath(it.path), name, null, editor.image.get());
|
||||
// console.log(it);
|
||||
});
|
||||
// let reader = new FileReader();
|
||||
// reader.onload = (e) => {
|
||||
// let result = e.target.result;
|
||||
// editor.image.insert(result, null, null, editor.image.get());
|
||||
// };
|
||||
// reader.readAsDataURL(files[0]);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
this.editor().on('froalaEditor.file.beforeUpload', (e, editor, files) => {
|
||||
// console.log(e, editor, files, 'blah blah blah')
|
||||
if (files.length) {
|
||||
let name = files[0].name;
|
||||
this.props.appstate.http.upload(files[0]).then(it => {
|
||||
editor.file.insert(this.http.appendImagePath(it.path), name, null);
|
||||
// console.log(it);
|
||||
});
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
this.editor().on('froalaEditor.video.beforeUpload', (e, editor, files) => {
|
||||
// console.log(e, editor, files, 'blah blah blah')
|
||||
if (files.length) {
|
||||
let name = files[0].name;
|
||||
// console.log(editor.video);
|
||||
this.props.appstate.http.upload(files[0]).then(it => {
|
||||
this.editor('video.insert', `<iframe controls="true" width="90%" height="100%" src="${this.http.appendImagePath(it.path)}" style="vertical-align:middle"/>`, false);
|
||||
// console.log(it);
|
||||
});
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Card>
|
||||
</div>
|
||||
<div className={"col s3"}>
|
||||
<Affix offsetTop={85}>
|
||||
<Card className="animated fadeIn cardLite">
|
||||
<div style={{padding: '14px'}}>
|
||||
<div className="row">
|
||||
<p className="label-form">Title Content</p>
|
||||
{wrapperText("title")(
|
||||
<Input placeholder="E.g. Title" autosize type={"text"}/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<p className="label-form">Tag</p>
|
||||
{wrapperSelect("tags")(
|
||||
<Select placeholder="Select a tag" style={{width: '100%',overflow: 'scroll'}}>
|
||||
{this.contentManagerStore.listTags.map(c => {
|
||||
return <Option key={c.id} value={c.id}>{c.name}</Option>
|
||||
})}
|
||||
</Select>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/*<div className="row">*/}
|
||||
{/*<p className="label-form">Types</p>*/}
|
||||
{/*{wrapperSelectType("type")(*/}
|
||||
{/*<Select placeholder="Select a type" style={{width: '100%',overflow: 'scroll'}}>*/}
|
||||
{/*<Option value="template1">Template Full Card</Option>*/}
|
||||
{/*<Option value="template2">Template Standart List</Option>*/}
|
||||
{/*/!*<Option value="template3">Template Surf & turf</Option>*!/*/}
|
||||
{/*</Select>*/}
|
||||
{/*)}*/}
|
||||
{/*</div>*/}
|
||||
|
||||
{this.state.visible == true ? (
|
||||
<div className="row">
|
||||
<p className="label-form">Items</p>
|
||||
{/*{wrapperSelectANT("items")(<Select*/}
|
||||
{/*mode="multiple"*/}
|
||||
{/*style={{ width: '100%' }}*/}
|
||||
{/*placeholder="E.g Dori,Cumi,Ikan"*/}
|
||||
{/*optionFilterProp="children"*/}
|
||||
{/*filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}*/}
|
||||
{/*>*/}
|
||||
{/*{this.contentManagerStore.listItems.map(data=>{*/}
|
||||
{/*return <Option key={data.id} value={data.id}>{data.name}</Option>*/}
|
||||
{/*})}*/}
|
||||
{/*</Select>)}*/}
|
||||
{wrapperTree("items")(
|
||||
<TreeSelect
|
||||
showSearch
|
||||
style={{ width: '100%' }}
|
||||
value={this.state.value}
|
||||
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
|
||||
placeholder="select a product"
|
||||
allowClear
|
||||
multiple
|
||||
treeDefaultExpandAll
|
||||
filterTreeNode={(input,treeNode)=>{
|
||||
// return lowerCase(treeNode.props.title).includes(lowerCase(input));
|
||||
return true;
|
||||
}}
|
||||
onSearch={async (input)=>{
|
||||
await this.contentManagerStore.getItem(input);
|
||||
}}
|
||||
onSelect={(value)=>{
|
||||
this.contentManagerStore.addSelectedItem(value);
|
||||
}}
|
||||
// treeData={[{value : 'cou',title:'cooo',selectable: false,children :[{value :'yeyeye',title :'KOKOKO'}]},
|
||||
// {value : 'skemberlu',title:'anehya',selectable: false,children :[{value :'ngerti',title :'nice'}]}]}
|
||||
treeData={this.contentManagerStore.itemSearch.slice().map((it,index)=>{
|
||||
return {
|
||||
value : it.user_store.id+index,
|
||||
title : it.user_store.name,
|
||||
selectable : false,
|
||||
children : [{
|
||||
value : it.id,
|
||||
title : it.name
|
||||
}]
|
||||
}
|
||||
})}
|
||||
>
|
||||
{/*<TreeNode value="parent 1" title="parent 1" key="0-1" disableCheckbox>*/}
|
||||
{/*<TreeNode value="parent 1-0" title="parent 1-0" key="0-1-1">*/}
|
||||
{/*<TreeNode value="leaf1" title="my leaf" key="random" />*/}
|
||||
{/*<TreeNode value="leaf2" title="your leaf" key="random1" />*/}
|
||||
{/*</TreeNode>*/}
|
||||
{/*<TreeNode value="parent 1-1" title="parent 1-1" key="random2">*/}
|
||||
{/*<TreeNode value="sss" title={<b style={{ color: '#08c' }}>sss</b>} key="random3" />*/}
|
||||
{/*<TreeNode value="leaf2" title="your leaf" key="random1" />*/}
|
||||
{/*</TreeNode>*/}
|
||||
{/*</TreeNode>*/}
|
||||
</TreeSelect>
|
||||
)}
|
||||
</div>
|
||||
) : ('')}
|
||||
|
||||
{this.props.match.params.id ? (<ButtonAntd type={'primary'} style={{width: '100%', marginTop: 25}} onClick={this.handleOpen} icon={'save'}>Save</ButtonAntd>) : (<ButtonAntd type={'primary'} style={{width: '100%', marginTop: 25}} onClick={this.handleOpen} icon={'upload'}>Publish</ButtonAntd>)}
|
||||
|
||||
|
||||
</div>
|
||||
</Card>
|
||||
</Affix>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Dialog
|
||||
title="Warning"
|
||||
actions={actions}
|
||||
modal={true}
|
||||
open={this.state.openedDialog}
|
||||
onRequestClose={() => this.handleClose()}
|
||||
>
|
||||
Make sure all of your data is correct before submitting.
|
||||
</Dialog>
|
||||
<Dialog
|
||||
title="Warning"
|
||||
actions={actionsBack}
|
||||
modal={true}
|
||||
contentStyle={{width: 350}}
|
||||
open={this.state.openedDialogBack}
|
||||
onRequestClose={() => this.handleBackClose()}
|
||||
>
|
||||
Are you sure you wanna go back ?
|
||||
</Dialog>
|
||||
|
||||
<Dialog
|
||||
title="Warning"
|
||||
actions={actionsDelete}
|
||||
modal={true}
|
||||
open={this.state.openDeleteDialog}
|
||||
onRequestClose={() => this.handleWarningDialog(false)}
|
||||
>
|
||||
Are you sure want to delete this item?
|
||||
</Dialog>
|
||||
|
||||
<Dialog
|
||||
title="Warning"
|
||||
actions={actionsEmpty}
|
||||
modal={true}
|
||||
contentStyle={{width: 350}}
|
||||
open={this.state.openedDialogEmpty}
|
||||
onRequestClose={() => this.handleEmptyClose()}
|
||||
>
|
||||
All data cannot be empty !
|
||||
</Dialog>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
218
src/common/pages/ContentManager/index.js
Normal file
218
src/common/pages/ContentManager/index.js
Normal file
@@ -0,0 +1,218 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import bind from 'bind-decorator';
|
||||
import {
|
||||
Card,
|
||||
FlatButton,
|
||||
Divider,
|
||||
RaisedButton,
|
||||
Toolbar,
|
||||
ToolbarGroup,
|
||||
ToolbarSeparator,
|
||||
Table,
|
||||
TableBody,
|
||||
TableHeader,
|
||||
TableHeaderColumn,
|
||||
TableRow,
|
||||
TableRowColumn,
|
||||
TextField,
|
||||
Dialog,
|
||||
Tab, Tabs,
|
||||
IconButton
|
||||
} from 'material-ui';
|
||||
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 ImageEdit from 'material-ui/svg-icons/image/edit';
|
||||
import EmptyComponent from '../EmptyComponent';
|
||||
import LoadingDialog from "../LoadingDialog";
|
||||
import Loader from 'react-loader-advanced';
|
||||
import {Link} from 'react-router-dom';
|
||||
import {LINKS} from "../../routes";
|
||||
import moment from 'moment';
|
||||
import {DIALOG} from "../../stores/global_ui";
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class ContentManager extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
value: 0,
|
||||
edit : false,
|
||||
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.contentManagerStore = props.appstate.contentManager;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.globalUI.openLoading();
|
||||
this.contentManagerStore.getList().then(res => {
|
||||
this.globalUI.closeLoading();
|
||||
});
|
||||
}
|
||||
|
||||
handleUpdateInput = (searchText) => {
|
||||
this.setState({
|
||||
searchText: searchText,
|
||||
});
|
||||
};
|
||||
|
||||
handleNewRequest = () => {
|
||||
this.setState({
|
||||
searchText: '',
|
||||
});
|
||||
};
|
||||
|
||||
tabsHandleChange = (value) => {
|
||||
this.setState({
|
||||
slideIndex: value,
|
||||
});
|
||||
};
|
||||
|
||||
deleteClicked = (id) => {
|
||||
this.setState({
|
||||
id : id,
|
||||
openedDelete: true
|
||||
});
|
||||
}
|
||||
|
||||
handleClickDelete = (id) => {
|
||||
this.contentManagerStore.delete(id).then(res=>{
|
||||
this.setState({
|
||||
openedDelete: false,
|
||||
openSnackbarDelete: true
|
||||
});
|
||||
this.globalUI.openSnackbar("Successful Deleted Existing Data");
|
||||
|
||||
}).catch(err=>{
|
||||
console.log(err);
|
||||
this.globalUI.openSnackbar(err.message);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
handleCloseDelete = () => {
|
||||
this.setState({
|
||||
openedDelete: false
|
||||
})
|
||||
}
|
||||
|
||||
handleChange = (event, index, value) => this.setState({value});
|
||||
|
||||
search = (event)=>{
|
||||
if(event.target.value.length == 0){
|
||||
this.contentManagerStore.isSearching = false;
|
||||
}
|
||||
else{
|
||||
this.contentManagerStore.isSearching = true;
|
||||
this.contentManagerStore.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 Content"
|
||||
style={{fontSize: 14}}
|
||||
hintStyle={{fontSize: 14}}
|
||||
underlineShow={false}
|
||||
onChange={this.search}
|
||||
/>
|
||||
</ToolbarGroup>
|
||||
<ToolbarGroup className="ToolbarGroupLast">
|
||||
<ToolbarSeparator/>
|
||||
<Link to={`${LINKS.FORM}`}>
|
||||
<RaisedButton className="ToolbarGroupLastButton" icon={<AddIcon/>} label="New Content"
|
||||
primary={true}/>
|
||||
</Link>
|
||||
</ToolbarGroup>
|
||||
</Toolbar>
|
||||
<Divider/>
|
||||
<div style={{paddingBottom: 5}}>
|
||||
<Loader show={this.globalUI.loadingVisibility} message={<LoadingDialog/>}
|
||||
messageStyle={{textAlign: 'center'}} backgroundStyle={{backgroundColor: 'rgba(255,255,255,0.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'}}>Title</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun" style={{height: 'auto'}}>Tag</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun" style={{height: 'auto'}}>Created At</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto', textAlign: 'right'}}>Action</TableHeaderColumn>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody displayRowCheckbox={false}>
|
||||
{(this.contentManagerStore.list.length > 0) ? (this.contentManagerStore.isSearching ? this.contentManagerStore.filtered : this.contentManagerStore.list).map((item, index) => {
|
||||
return (
|
||||
<TableRow key={item.id}>
|
||||
<TableRowColumn>
|
||||
<div>
|
||||
<Link to={`${LINKS.FORM}/${item.id}`} key={item.id}>{item.title}</Link>
|
||||
</div>
|
||||
</TableRowColumn><TableRowColumn>{item.tags[0].tag.name}</TableRowColumn>
|
||||
<TableRowColumn>{moment(item.created_at).format('DD MMMM YYYY, HH:mm:ss')}</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>
|
||||
</Loader>
|
||||
</div>
|
||||
<Dialog
|
||||
title="Warning"
|
||||
actions={actionsDelete}
|
||||
modal={true}
|
||||
open={this.state.openedDelete}
|
||||
onRequestClose={() => this.handleCloseDelete()}
|
||||
>
|
||||
Are you sure want to delete this data?
|
||||
</Dialog>
|
||||
{/* {this.state.edit ? <DialogCreate mode="update" defaultValue={Object.assign({},this.state.defaultValue)}/> : <DialogCreate mode="create"/>} */}
|
||||
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
}
|
||||
294
src/common/pages/CustomMenus/Dialog/CategoryData.js
Normal file
294
src/common/pages/CustomMenus/Dialog/CategoryData.js
Normal 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>
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
3
src/common/pages/CustomMenus/Dialog/icons.js
Normal file
3
src/common/pages/CustomMenus/Dialog/icons.js
Normal 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"
|
||||
];
|
||||
309
src/common/pages/CustomMenus/Dialog/index.js
Normal file
309
src/common/pages/CustomMenus/Dialog/index.js
Normal 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>
|
||||
)
|
||||
}
|
||||
}
|
||||
238
src/common/pages/CustomMenus/index.js
Normal file
238
src/common/pages/CustomMenus/index.js
Normal 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>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import CustomerForm from './../../Customers/CustomerDialog/CustomerForm';
|
||||
import {DIALOG} from "../../../stores/global_ui";
|
||||
import {Dialog, FlatButton, RaisedButton} from "material-ui";
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class UpdateDialogCompenent extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
|
||||
this.customer = props.appstate.customer;
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
||||
}
|
||||
|
||||
onChangeForm(formData) {
|
||||
this.setState({formData});
|
||||
}
|
||||
|
||||
save() {
|
||||
this.customer.update(this.customer.selectedCustomer.id, this.state.formData)
|
||||
.then(res => {
|
||||
this.globalUI.hideDialog(DIALOG.CUSTOMER.UPDATE);
|
||||
this.customer.getAll();
|
||||
this.customer.getDetail(this.customer.selectedCustomer.id);
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const actions = [
|
||||
<FlatButton
|
||||
label="Cancel"
|
||||
primary={true}
|
||||
style={{marginRight: 10}}
|
||||
onClick={() => this.globalUI.hideDialog(DIALOG.CUSTOMER.UPDATE)}
|
||||
/>,
|
||||
<RaisedButton
|
||||
label="Submit"
|
||||
primary={true}
|
||||
onClick={() => this.save()}
|
||||
/>,
|
||||
];
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
title="Update Costumer"
|
||||
modal={false}
|
||||
actions={actions}
|
||||
open={this.globalUI[DIALOG.CUSTOMER.UPDATE]}
|
||||
onRequestClose={this.handleClose}>
|
||||
<CustomerForm defaultValue={this.customer.selectedCustomer} onChangeData={this.onChangeForm.bind(this)} />
|
||||
</Dialog> )
|
||||
}
|
||||
}
|
||||
561
src/common/pages/CustomerDetail/GeneralInformation/index.js
Normal file
561
src/common/pages/CustomerDetail/GeneralInformation/index.js
Normal file
@@ -0,0 +1,561 @@
|
||||
import React from 'react';
|
||||
import {inject, observer} from 'mobx-react';
|
||||
import {
|
||||
Paper,
|
||||
SelectField,
|
||||
CardMedia,
|
||||
Card,
|
||||
CardText,
|
||||
CardTitle,
|
||||
Divider,
|
||||
MenuItem,
|
||||
RaisedButton,
|
||||
Toolbar,
|
||||
ToolbarGroup,
|
||||
ToolbarTitle,
|
||||
FlatButton,
|
||||
Dialog,
|
||||
TextField,
|
||||
DatePicker
|
||||
} from 'material-ui';
|
||||
import AddIcon from 'material-ui/svg-icons/image/edit';
|
||||
import moment from "moment";
|
||||
import {Link} from 'react-router-dom';
|
||||
import {LINKS} from "../../../routes";
|
||||
import {DIALOG} from "../../../stores/global_ui";
|
||||
import UpdateDialog from './UpdateDialog';
|
||||
import IdentificationPassport from './../../Customers/CustomerDialog/IdentificationPassport';
|
||||
|
||||
// import './style.scss';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class GeneralInformation extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.customer = props.appstate.customer;
|
||||
this.state = {
|
||||
value: 1,
|
||||
searchText: '',
|
||||
slideIndex: 0,
|
||||
openedDialog:false,
|
||||
gender:this.customer.CustomerData.gender,
|
||||
marital:this.customer.CustomerData.martial_status,
|
||||
openedDialogPhoto:false
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.http = props.appstate.http;
|
||||
this.authStore = props.appstate.auth;
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
console.log('Profile loaded!');
|
||||
|
||||
}
|
||||
editData = (id) => {
|
||||
this.customer.update(id);
|
||||
this.setState({openedDialog: false});
|
||||
this.setState({openedDialogPhoto: false});
|
||||
};
|
||||
|
||||
handleOpenDialog = () => {
|
||||
this.setState({
|
||||
openedDialog:true
|
||||
});
|
||||
};
|
||||
|
||||
handleCloseDialog = () =>{
|
||||
this.setState({
|
||||
openedDialog:false
|
||||
});
|
||||
}
|
||||
|
||||
handleOpenPhoto = () => {
|
||||
this.setState({
|
||||
openedDialogPhoto:true,
|
||||
oldPassportPhoto : this.customer.CustomerData.passport_photo,
|
||||
oldIdPhoto : this.customer.CustomerData.id_photo,
|
||||
});
|
||||
console.log
|
||||
|
||||
}
|
||||
|
||||
handleClosePhoto = () =>{
|
||||
this.setState({
|
||||
openedDialogPhoto:false
|
||||
});
|
||||
this.customer.CustomerData.passport_photo = this.state.oldPassportPhoto;
|
||||
this.customer.CustomerData.id_photo = this.state.oldIdPhoto;
|
||||
}
|
||||
|
||||
handleUpdateInput = (searchText) => {
|
||||
this.setState({
|
||||
searchText: searchText,
|
||||
});
|
||||
};
|
||||
|
||||
handleNewRequest = () => {
|
||||
this.setState({
|
||||
searchText: '',
|
||||
});
|
||||
};
|
||||
|
||||
tabsHandleChange = (value) => {
|
||||
this.setState({
|
||||
slideIndex: value,
|
||||
});
|
||||
};
|
||||
|
||||
handleChange = (event, index, value) => this.setState({value});
|
||||
|
||||
handleChangeName = (event) =>{
|
||||
this.customer.CustomerData.name = event.target.value;
|
||||
};
|
||||
|
||||
handleChangeEmail = (event) =>{
|
||||
this.customer.CustomerData.email = event.target.value;
|
||||
};
|
||||
|
||||
handleChangeDate = (event, value) =>{
|
||||
this.customer.CustomerData.date_of_birth = value;
|
||||
};
|
||||
|
||||
handleChangeGender = (event, index, value) =>{
|
||||
this.customer.CustomerData.gender = value;
|
||||
};
|
||||
|
||||
handleChangePassport = (event) =>{
|
||||
this.customer.CustomerData.passport_number = event.target.value;
|
||||
};
|
||||
|
||||
handleChangeOccupation = (event) =>{
|
||||
this.customer.CustomerData.occupation = event.target.value;
|
||||
};
|
||||
|
||||
handleChangeAddress = (event) =>{
|
||||
this.customer.CustomerData.address = event.target.value;
|
||||
};
|
||||
|
||||
handleChangeBirthPlace = (event) =>{
|
||||
this.customer.CustomerData.birth_place = event.target.value;
|
||||
};
|
||||
|
||||
handleChangePhone = (event) =>{
|
||||
this.customer.CustomerData.phone = event.target.value;
|
||||
};
|
||||
|
||||
handleChangeHandphone = (event) =>{
|
||||
this.customer.CustomerData.handphone = event.target.value;
|
||||
};
|
||||
|
||||
handleChangeMarital = (event, index, value) =>{
|
||||
this.customer.CustomerData.martial_status = value;
|
||||
};
|
||||
|
||||
handleChangeTaxNumber = (event) =>{
|
||||
this.customer.CustomerData.id_tax_number = event.target.value;
|
||||
};
|
||||
|
||||
handleChangeType = (event) =>{
|
||||
this.customer.CustomerData.id_type = event.target.value;
|
||||
};
|
||||
|
||||
handleChangeNumber= (event) =>{
|
||||
this.customer.CustomerData.id_number = event.target.value;
|
||||
};
|
||||
|
||||
render() {
|
||||
const styles = {
|
||||
|
||||
radioButton: {
|
||||
marginBottom: 16,
|
||||
},
|
||||
};
|
||||
|
||||
const gender = [
|
||||
<MenuItem key={0} value={0} primaryText="Choose Gender"/>,
|
||||
<MenuItem key={1} value={"Man"} primaryText="Man"/>,
|
||||
<MenuItem key={2} value={"Woman"} primaryText="Woman"/>,
|
||||
];
|
||||
|
||||
const marital_status = [
|
||||
<MenuItem key={0} value={0} primaryText="Choose Marital Status"/>,
|
||||
<MenuItem key={1} value={"Married"} primaryText="Married"/>,
|
||||
<MenuItem key={2} value={"Single"} primaryText="Single"/>,
|
||||
<MenuItem key={2} value={"Divorced"} primaryText="Divorced"/>,
|
||||
<MenuItem key={2} value={"Widowed"} primaryText="Widowed"/>,
|
||||
];
|
||||
|
||||
const actions = [
|
||||
<FlatButton
|
||||
label="Cancel"
|
||||
primary={true}
|
||||
onClick={this.handleCloseDialog}
|
||||
/>,
|
||||
<FlatButton
|
||||
label="Submit"
|
||||
primary={true}
|
||||
onClick={() => this.editData(this.customer.CustomerData.id)}
|
||||
/>,
|
||||
];
|
||||
|
||||
const actionsPhoto = [
|
||||
<FlatButton
|
||||
label="Cancel"
|
||||
primary={true}
|
||||
onClick={this.handleClosePhoto}
|
||||
/>,
|
||||
<FlatButton
|
||||
label="Submit"
|
||||
primary={true}
|
||||
onClick={() => this.editData(this.customer.CustomerData.id)}
|
||||
/>,
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="animated fadeIn">
|
||||
<UpdateDialog/>
|
||||
<Card className="row" style={{marginBottom: 10}}>
|
||||
<div className="flexSpaceBetween" style={{padding: 16}}>
|
||||
<CardTitle style={{padding: 0, fontSize: 22}} titleStyle={{fontSize: 22}}
|
||||
title={this.customer.CustomerData.name}
|
||||
subtitle={<code>{this.customer.CustomerData.id}</code>}/>
|
||||
<ToolbarGroup>
|
||||
<RaisedButton
|
||||
icon={<AddIcon/>}
|
||||
label="Edit"
|
||||
onClick={this.handleOpenDialog}
|
||||
primary={true}/>
|
||||
</ToolbarGroup>
|
||||
|
||||
</div>
|
||||
</Card>
|
||||
<Card style={{marginBottom: 10}}>
|
||||
<Toolbar className="toolbarCard" style={{backgroundColor: '#fff'}}>
|
||||
<ToolbarGroup>
|
||||
<ToolbarTitle style={{fontSize: 14, fontWeight: 500, color: '#32325d', textTransform: 'capitalize'}}
|
||||
text={'Details'}/>
|
||||
</ToolbarGroup>
|
||||
|
||||
</Toolbar>
|
||||
<Divider/>
|
||||
<CardTitle style={{paddingBottom: 0}}
|
||||
subtitle={<p style={{color: '#32325d', fontSize: 12, paddingLeft: 10}}>ACCOUNT INFORMATION</p>}/>
|
||||
<CardText>
|
||||
<div className="row">
|
||||
<div className="col s12 m12 l12">
|
||||
<div className="listCustDetail">
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">ID</p>
|
||||
<code className="listCustomerDetailItemValue">{this.customer.CustomerData.id}</code>
|
||||
</div>
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">Created</p>
|
||||
<p
|
||||
className="listCustomerDetailItemValue">{moment(this.customer.CustomerData.created_at).format('DD MMMM YYYY, HH:mm:ss')}</p>
|
||||
</div>
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">Email</p>
|
||||
<p className="listCustomerDetailItemValue">{this.customer.CustomerData.email}</p>
|
||||
</div>
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">Birth Place</p>
|
||||
<p className="listCustomerDetailItemValue">{this.customer.CustomerData.birth_place}</p>
|
||||
</div>
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">Date of Birth</p>
|
||||
<p
|
||||
className="listCustomerDetailItemValue">{moment(this.customer.CustomerData.date_of_birth).format('DD MMMM YYYY')}</p>
|
||||
</div>
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">Gender</p>
|
||||
<p className="listCustomerDetailItemValue">{this.customer.CustomerData.gender}</p>
|
||||
</div>
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">Address</p>
|
||||
<p className="listCustomerDetailItemValue">{this.customer.CustomerData.address}</p>
|
||||
</div>
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">Occupation</p>
|
||||
<p className="listCustomerDetailItemValue">{this.customer.CustomerData.occupation}</p>
|
||||
</div>
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">Phone</p>
|
||||
<p className="listCustomerDetailItemValue">{this.customer.CustomerData.phone}</p>
|
||||
</div>
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">Handphone</p>
|
||||
<p className="listCustomerDetailItemValue">{this.customer.CustomerData.handphone}</p>
|
||||
</div>
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">Marital Status</p>
|
||||
<p className="listCustomerDetailItemValue">{this.customer.CustomerData.martial_status}</p>
|
||||
</div>
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">ID Tax Number</p>
|
||||
<p className="listCustomerDetailItemValue">{this.customer.CustomerData.id_tax_number}</p>
|
||||
</div>
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">ID Type</p>
|
||||
<p className="listCustomerDetailItemValue">{this.customer.CustomerData.id_type}</p>
|
||||
</div>
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">ID Number</p>
|
||||
<p className="listCustomerDetailItemValue">{this.customer.CustomerData.id_number}</p>
|
||||
</div>
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">Passport Number</p>
|
||||
<p className="listCustomerDetailItemValue">{this.customer.CustomerData.passport_number}</p>
|
||||
</div>
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">Agent</p>
|
||||
<p className="listCustomerDetailItemValue"><Link to={`${LINKS.MEMBER}/${this.customer.CustomerData.agent_id}`}
|
||||
key={this.customer.CustomerData.agent_id}>{this.customer.CustomerData.agent}</Link> - <code
|
||||
style={{color: '#424770'}}>{this.customer.CustomerData.agent_id}</code></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardText>
|
||||
</Card>
|
||||
<Card className="row" style={{marginBottom: 10}}>
|
||||
<ToolbarGroup className="flexSpaceBetween" style={{padding: "0px 16px 0px 16px"}}>
|
||||
<ToolbarTitle style={{fontSize: 14, fontWeight: 500, color: '#32325d', textTransform: 'capitalize'}}
|
||||
text={'Identification & Passport'}/>
|
||||
<RaisedButton
|
||||
icon={<AddIcon/>}
|
||||
label="Edit"
|
||||
onClick={this.handleOpenPhoto}
|
||||
primary={true}/>
|
||||
</ToolbarGroup>
|
||||
<Divider/>
|
||||
<div className="row">
|
||||
<div className="col s12 m6 l6">
|
||||
<CardTitle style={{paddingBottom: 0}}
|
||||
subtitle={<p style={{color: '#32325d', fontSize: 12}}>IDENTIFICATION</p>}/>
|
||||
<CardText>
|
||||
<Paper zDepth={1} style={{padding: 8}}>
|
||||
<CardMedia style={{minHeight: '222px'}}>
|
||||
<img src={this.http.appendImagePath(this.customer.CustomerData.id_photo)}/>
|
||||
</CardMedia>
|
||||
</Paper>
|
||||
</CardText>
|
||||
</div>
|
||||
<div className="col s12 m6 l6">
|
||||
<CardTitle style={{paddingBottom: 0}}
|
||||
subtitle={<p style={{color: '#32325d', fontSize: 12}}>PASSPORT</p>}/>
|
||||
<CardText>
|
||||
<Paper zDepth={1} style={{padding: 8}}>
|
||||
<CardMedia style={{minHeight: '222px'}}>
|
||||
<img src={this.http.appendImagePath(this.customer.CustomerData.passport_photo)}/>
|
||||
</CardMedia>
|
||||
</Paper>
|
||||
</CardText>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
<Dialog
|
||||
title="Update Customer Data"
|
||||
actions={actions}
|
||||
modal={true}
|
||||
open={this.state.openedDialog}
|
||||
onRequestClose={() => this.handleCloseDialog()}
|
||||
>
|
||||
<div className="row">
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Name</p>
|
||||
<TextField
|
||||
fullWidth={true}
|
||||
onChange={this.handleChangeName}
|
||||
hintText="E.g. Michael Jordan"
|
||||
value={this.customer.CustomerData.name}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Email</p>
|
||||
<TextField
|
||||
fullWidth={true}
|
||||
onChange={this.handleChangeEmail}
|
||||
hintText="E.g. Michael.Jordan@domain.com"
|
||||
value={this.customer.CustomerData.email}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Date of Birth</p>
|
||||
<DatePicker
|
||||
fullWidth={true}
|
||||
mode="landscape"
|
||||
onChange={this.handleChangeDate}
|
||||
hintText="2017-08-17"
|
||||
openToYearSelection={true}
|
||||
value={this.customer.CustomerData.date_of_birth}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Gender</p>
|
||||
<SelectField
|
||||
value={this.customer.CustomerData.gender}
|
||||
onChange={this.handleChangeGender}
|
||||
fullWidth={true}
|
||||
>
|
||||
{gender}
|
||||
</SelectField>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Passport Number</p>
|
||||
<TextField
|
||||
hintText="E.g. X000000"
|
||||
onChange={this.handleChangePassport}
|
||||
fullWidth={true}
|
||||
value={this.customer.CustomerData.passport_number}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Occupation</p>
|
||||
<TextField
|
||||
hintText="E.g. PNS"
|
||||
onChange={this.handleChangeOccupation}
|
||||
fullWidth={true}
|
||||
value={this.customer.CustomerData.occupation}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Address</p>
|
||||
<TextField
|
||||
hintText="E.g. Jl. Kemanggisan No.25 Jakarta Barat"
|
||||
multiLine={true}
|
||||
fullWidth={true}
|
||||
rows={1}
|
||||
rowsMax={4}
|
||||
onChange={this.handleChangeAddress}
|
||||
value={this.customer.CustomerData.address}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Birth Place</p>
|
||||
<TextField
|
||||
hintText="E.g. Bandung"
|
||||
fullWidth={true}
|
||||
onChange={this.handleChangeBirthPlace}
|
||||
value={this.customer.CustomerData.birth_place}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Phone</p>
|
||||
<TextField
|
||||
hintText="E.g. 88954361"
|
||||
onChange={this.handleChangePhone}
|
||||
fullWidth={true}
|
||||
value={this.customer.CustomerData.phone}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Handphone</p>
|
||||
<TextField
|
||||
hintText="E.g. 0899976487"
|
||||
onChange={this.handleChangeHandphone}
|
||||
fullWidth={true}
|
||||
value={this.customer.CustomerData.handphone}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Marital Status</p>
|
||||
<SelectField
|
||||
value={this.customer.CustomerData.martial_status}
|
||||
onChange={this.handleChangeMarital}
|
||||
fullWidth={true}
|
||||
>
|
||||
{marital_status}
|
||||
</SelectField>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">ID Tax Number</p>
|
||||
<TextField
|
||||
hintText="E.g. 00000000000000000"
|
||||
onChange={this.handleChangeTaxNumber}
|
||||
fullWidth={true}
|
||||
value={this.customer.CustomerData.id_tax_number}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">ID Type</p>
|
||||
<TextField
|
||||
hintText="E.g. KTP"
|
||||
onChange={this.handleChangeType}
|
||||
fullWidth={true}
|
||||
value={this.customer.CustomerData.id_type}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">ID Number</p>
|
||||
<TextField
|
||||
hintText="E.g. 00000000000000"
|
||||
onChange={this.handleChangeNumber}
|
||||
fullWidth={true}
|
||||
value={this.customer.CustomerData.id_number}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
<Dialog
|
||||
title="Update Agent"
|
||||
actions={actionsPhoto}
|
||||
modal={true}
|
||||
open={this.state.openedDialogPhoto}
|
||||
onRequestClose={() => this.handleClosePhoto()}
|
||||
>
|
||||
<IdentificationPassport/>
|
||||
</Dialog>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
197
src/common/pages/CustomerDetail/Order/index.js
Normal file
197
src/common/pages/CustomerDetail/Order/index.js
Normal file
@@ -0,0 +1,197 @@
|
||||
import React from 'react';
|
||||
import {inject, observer} from 'mobx-react';
|
||||
import {
|
||||
Card,
|
||||
Divider,
|
||||
MenuItem,
|
||||
RaisedButton,
|
||||
Table,
|
||||
TableBody,
|
||||
TableHeader,
|
||||
TableHeaderColumn,
|
||||
TableRow,
|
||||
TableRowColumn,
|
||||
TextField,
|
||||
Toolbar,
|
||||
ToolbarGroup,
|
||||
ToolbarSeparator
|
||||
} from 'material-ui';
|
||||
import SearchIcon from 'material-ui/svg-icons/action/search';
|
||||
import AddIcon from 'material-ui/svg-icons/content/add';
|
||||
import moment from "moment";
|
||||
import {Link} from 'react-router-dom';
|
||||
import {LINKS} from "../../../routes";
|
||||
import get from 'lodash.get';
|
||||
import EmptyComponent from "../../EmptyComponent/index";
|
||||
|
||||
// import './style.scss';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class CustomerOrder extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
value: 1,
|
||||
searchText: '',
|
||||
slideIndex: 0,
|
||||
customers: [
|
||||
{
|
||||
id: 'ATT001',
|
||||
package: 'The Exoticsm Of Minang',
|
||||
registered: moment(),
|
||||
status: 'active'
|
||||
},
|
||||
{
|
||||
id: 'ATT002',
|
||||
package: 'Weh Island Wonderful Adventure',
|
||||
registered: moment(),
|
||||
status: 'blocked'
|
||||
},
|
||||
{
|
||||
id: 'ATT003',
|
||||
package: 'Holy Land',
|
||||
registered: moment(),
|
||||
status: 'pending'
|
||||
},
|
||||
{
|
||||
id: 'ATT004',
|
||||
package: 'Legoland & Gardens By The Bay 4D',
|
||||
registered: moment(),
|
||||
status: 'clear'
|
||||
},
|
||||
]
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.http = props.appstate.http;
|
||||
this.authStore = props.appstate.auth;
|
||||
this.customer = props.appstate.customer;
|
||||
this.order = props.appstate.order;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
console.log('Profile loaded!', this.props);
|
||||
this.customer.getOrder()
|
||||
|
||||
}
|
||||
|
||||
handleUpdateInput = (searchText) => {
|
||||
this.setState({
|
||||
searchText: searchText,
|
||||
});
|
||||
};
|
||||
|
||||
handleNewRequest = () => {
|
||||
this.setState({
|
||||
searchText: '',
|
||||
});
|
||||
};
|
||||
|
||||
tabsHandleChange = (value) => {
|
||||
this.setState({
|
||||
slideIndex: value,
|
||||
});
|
||||
};
|
||||
|
||||
handleChange = (event, index, value) => this.setState({value});
|
||||
|
||||
render() {
|
||||
const styles = {
|
||||
|
||||
radioButton: {
|
||||
marginBottom: 16,
|
||||
},
|
||||
};
|
||||
|
||||
const colors = [
|
||||
'Jakarta - Soekarno - Hatta (CGK)',
|
||||
'Bali',
|
||||
'Surabaya',
|
||||
'Yogyakarta',
|
||||
'Aceh',
|
||||
'Kalimantan',
|
||||
'Medan',
|
||||
'Papua',
|
||||
];
|
||||
|
||||
const items = [
|
||||
<MenuItem key={1} value={1} primaryText="All Maskapai"/>,
|
||||
<MenuItem key={2} value={2} primaryText="Air Asia"/>,
|
||||
<MenuItem key={3} value={3} primaryText="Weeknights"/>,
|
||||
<MenuItem key={4} value={4} primaryText="Weekends"/>,
|
||||
<MenuItem key={5} value={5} primaryText="Weekly"/>,
|
||||
];
|
||||
|
||||
const count = [
|
||||
<MenuItem key={1} value={1} primaryText="1"/>,
|
||||
<MenuItem key={2} value={2} primaryText="2"/>,
|
||||
<MenuItem key={3} value={3} primaryText="3"/>,
|
||||
<MenuItem key={4} value={4} primaryText="4"/>,
|
||||
<MenuItem key={5} value={5} primaryText="5"/>,
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="animated fadeIn">
|
||||
<Card>
|
||||
<Toolbar className="toolbarCard" style={{backgroundColor: '#fff'}}>
|
||||
<ToolbarGroup>
|
||||
<SearchIcon style={{marginRight: 8, color: "#999"}}/>
|
||||
<TextField
|
||||
hintText="Search Order"
|
||||
style={{fontSize: 14}}
|
||||
hintStyle={{fontSize: 14}}
|
||||
underlineShow={false}
|
||||
/>
|
||||
</ToolbarGroup>
|
||||
{/*<ToolbarGroup className="ToolbarGroupLast">*/}
|
||||
{/*<ToolbarSeparator/>*/}
|
||||
{/*<RaisedButton className="ToolbarGroupLastButton" icon={<AddIcon/>} label="New Customer" primary={true} />*/}
|
||||
{/*</ToolbarGroup>*/}
|
||||
</Toolbar>
|
||||
<Divider/>
|
||||
<div>
|
||||
<Table selectable={false}>
|
||||
<TableHeader displaySelectAll={false}
|
||||
adjustForCheckbox={false}
|
||||
enableSelectAll={false}>
|
||||
<TableRow style={{height: 38, background: '#f6f9fc'}}>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun" style={{height: 'auto'}}>Order
|
||||
Id</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Type</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Name</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Ordered</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Status</TableHeaderColumn>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody displayRowCheckbox={false}>
|
||||
{(this.customer.orders.length > 0) ?
|
||||
this.customer.orders.map(cust => {
|
||||
return (
|
||||
<TableRow key={cust.id}>
|
||||
<TableRowColumn><Link to={(cust.type === 'airline') ? `${LINKS.ORDER_DETAIL_AIRLINES_WO_ID}/${cust.id}` : `${LINKS.ORDER}/${cust.id}`} key={cust.id} onClick={() => {
|
||||
this.order.setOrderDetail(cust);
|
||||
// this.props.history.push();
|
||||
}}>{cust.id}</Link></TableRowColumn>
|
||||
<TableRowColumn>{cust.type}</TableRowColumn>
|
||||
<TableRowColumn>{cust.name}</TableRowColumn>
|
||||
<TableRowColumn>{moment(cust.created_at).format("DD MMMM YYYY, HH:mm:ss")}</TableRowColumn>
|
||||
<TableRowColumn>{cust.status}</TableRowColumn>
|
||||
</TableRow>
|
||||
)
|
||||
}) : <EmptyComponent type="empty" header="" content="There is no data in sight"/>
|
||||
}
|
||||
</TableBody>
|
||||
</Table>
|
||||
|
||||
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import {Dialog, FlatButton, Stepper, Step, StepLabel, Snackbar} from "material-ui";
|
||||
import {DIALOG} from "../../../../stores/global_ui";
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class CancelPaymentDialog extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
currentStep: 0,
|
||||
prevText: "Cancel",
|
||||
nextText: "Submit"
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
this.order = props.appstate.order;
|
||||
this.http = props.appstate.http;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
||||
}
|
||||
|
||||
makePayment() {
|
||||
return this.http.post("payments/cancel", {
|
||||
package_transaction_id: this.order.selectedOrder.id
|
||||
})
|
||||
.then(res => {
|
||||
this.order.getDetail(this.order.selectedOrder.id);
|
||||
this.globalUI.hideDialog(DIALOG.ORDER.CANCEL_PAYMENT);
|
||||
})
|
||||
}
|
||||
|
||||
handleNext = () => this.makePayment();
|
||||
handleClose = () => this.globalUI.hideDialog(DIALOG.ORDER.CANCEL_PAYMENT);
|
||||
|
||||
render() {
|
||||
|
||||
const actions = [
|
||||
<FlatButton
|
||||
label={this.state.prevText}
|
||||
primary={true}
|
||||
onClick={() => this.globalUI.hideDialog(DIALOG.ORDER.CANCEL_PAYMENT)}
|
||||
/>,
|
||||
<FlatButton
|
||||
label={this.state.nextText}
|
||||
primary={true}
|
||||
onClick={() => this.handleNext().catch(err => this.props.appstate.globalUI.openSnackbar(err.message))}
|
||||
/>,
|
||||
];
|
||||
|
||||
const actionsCancelOnly = [
|
||||
<FlatButton
|
||||
label={"Ok"}
|
||||
primary={true}
|
||||
onClick={() => this.globalUI.hideDialog(DIALOG.ORDER.CANCEL_PAYMENT)}
|
||||
/>,
|
||||
]
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
title="Cancel a Payment"
|
||||
modal={false}
|
||||
actions={actions}
|
||||
open={this.globalUI[DIALOG.ORDER.CANCEL_PAYMENT]}
|
||||
onRequestClose={this.handleClose}>
|
||||
Are you sure want to cancel this book?
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import {DIALOG} from "../../../../stores/global_ui";
|
||||
import NumberFormat from 'react-number-format';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class BookedOrder extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
|
||||
this.http = props.appstate.http;
|
||||
this.order = props.appstate.order;
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
}
|
||||
|
||||
makePayment() {
|
||||
return this.http.post("payments/add_payment", {
|
||||
package_transaction_id: this.order.selectedOrder.id
|
||||
})
|
||||
.then(res => {
|
||||
this.order.getDetail(this.order.selectedOrder.id);
|
||||
this.globalUI.hideDialog(DIALOG.ORDER.MAKE_PAYMENT);
|
||||
})
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
||||
const {parent} = this.props;
|
||||
|
||||
setTimeout(() => {
|
||||
parent.setState({
|
||||
handleNext: () => this.makePayment()
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
You'll pay <NumberFormat value={this.order.selectedOrder.installment_amount} displayType={'text'} thousandSeparator={true} prefix={'IDR '}/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import {DIALOG} from "../../../../stores/global_ui";
|
||||
import NumberFormat from 'react-number-format';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class CompletedOrder extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
|
||||
this.http = props.appstate.http;
|
||||
this.order = props.appstate.order;
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
}
|
||||
|
||||
// makePayment() {
|
||||
// this.http.post("payments/add_payment", {
|
||||
// package_transaction_id: this.order.selectedOrder.id
|
||||
// })
|
||||
// .then(res => {
|
||||
// this.order.getDetail(this.order.selectedOrder.id);
|
||||
// this.globalUI.hideDialog(DIALOG.ORDER.MAKE_PAYMENT);
|
||||
// })
|
||||
// }
|
||||
|
||||
componentDidMount() {
|
||||
|
||||
const {parent} = this.props;
|
||||
|
||||
setTimeout(() => {
|
||||
parent.setState({
|
||||
handleNext: () => {return true}
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
Your payment is already completed
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import {DIALOG} from "../../../../stores/global_ui";
|
||||
import NumberFormat from 'react-number-format';
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class OrderedOrder extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
amount: 0,
|
||||
isLoading: true
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
|
||||
this.http = props.appstate.http;
|
||||
this.order = props.appstate.order;
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
}
|
||||
|
||||
makePayment() {
|
||||
return this.http.post("payments/initial_payment", {
|
||||
package_transaction_id: this.order.selectedOrder.id
|
||||
})
|
||||
.then(res => {
|
||||
this.order.getDetail(this.order.selectedOrder.id);
|
||||
this.globalUI.hideDialog(DIALOG.ORDER.MAKE_PAYMENT);
|
||||
})
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
||||
const {parent} = this.props;
|
||||
|
||||
this.setState({isLoading: true});
|
||||
|
||||
this.http.post("payments/initial_payment_preview", {
|
||||
package_transaction_id: this.order.selectedOrder.id
|
||||
})
|
||||
.then(res => {
|
||||
|
||||
parent.setState({
|
||||
handleNext: () => this.makePayment()
|
||||
});
|
||||
|
||||
this.setState({
|
||||
isLoading: false,
|
||||
amount: res.amount
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
You'll pay <NumberFormat value={this.state.amount} displayType={'text'} thousandSeparator={true} prefix={'IDR '}/> as DownPayment
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import {MenuItem, SelectField} from "material-ui";
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class SelectPaymentType extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<SelectField>
|
||||
<MenuItem value={"cash"} primaryText="Cash" />
|
||||
</SelectField>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import {Dialog, FlatButton, Stepper, Step, StepLabel, Snackbar} from "material-ui";
|
||||
import {DIALOG} from "../../../../stores/global_ui";
|
||||
import SelectPaymentType from "./SelectPaymentType";
|
||||
|
||||
import BookedOrder from './BookedOrder';
|
||||
import OrderedOrder from './OrderedOrder';
|
||||
import CompleteOrder from './CompleteOrder';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class MakePaymentDialog extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
currentStep: 0,
|
||||
handleNext: () => {},
|
||||
prevText: "Cancel",
|
||||
nextText: "Submit"
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
this.order = props.appstate.order;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
||||
}
|
||||
|
||||
getContent() {
|
||||
switch (this.order.selectedOrder.status) {
|
||||
case "ordered":
|
||||
return <OrderedOrder parent={this} />;
|
||||
case "booked":
|
||||
return <BookedOrder parent={this} />;
|
||||
case "payment_complete":
|
||||
return <CompleteOrder parent={this} />;
|
||||
default:
|
||||
return <div/>;
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const actions = [
|
||||
<FlatButton
|
||||
label={this.state.prevText}
|
||||
primary={true}
|
||||
onClick={() => this.globalUI.hideDialog(DIALOG.ORDER.MAKE_PAYMENT)}
|
||||
/>,
|
||||
<FlatButton
|
||||
label={this.state.nextText}
|
||||
primary={true}
|
||||
onClick={() => this.state.handleNext().catch(err => this.props.appstate.globalUI.openSnackbar(err.message))}
|
||||
/>,
|
||||
];
|
||||
|
||||
const actionsCancelOnly = [
|
||||
<FlatButton
|
||||
label={"Ok"}
|
||||
primary={true}
|
||||
onClick={() => this.globalUI.hideDialog(DIALOG.ORDER.MAKE_PAYMENT)}
|
||||
/>,
|
||||
]
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
title="Make a Payment"
|
||||
modal={false}
|
||||
actions={(this.order.selectedOrder.status === 'payment_complete') ? actionsCancelOnly : actions}
|
||||
open={this.globalUI[DIALOG.ORDER.MAKE_PAYMENT]}
|
||||
onRequestClose={this.handleClose}>
|
||||
{this.getContent()}
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
}
|
||||
413
src/common/pages/CustomerDetail/OrderDetail/index.js
Normal file
413
src/common/pages/CustomerDetail/OrderDetail/index.js
Normal file
@@ -0,0 +1,413 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import {
|
||||
Card, CardTitle, CardText,
|
||||
Divider,
|
||||
MenuItem,
|
||||
FlatButton,
|
||||
RaisedButton,
|
||||
Table,
|
||||
TableBody,
|
||||
TableHeader,
|
||||
TableHeaderColumn,
|
||||
TableRow,
|
||||
TableRowColumn,
|
||||
TextField,
|
||||
Toolbar,
|
||||
ToolbarGroup,
|
||||
ToolbarSeparator, ToolbarTitle, CardHeader, Dialog,
|
||||
} from 'material-ui';
|
||||
import {Link} from 'react-router-dom';
|
||||
import {LINKS} from "../../../routes";
|
||||
import {DIALOG} from "../../../stores/global_ui";
|
||||
import AddIcon from 'material-ui/svg-icons/content/add';
|
||||
import RemoveIcon from 'material-ui/svg-icons/content/remove';
|
||||
import NavigationArrowBack from 'material-ui/svg-icons/navigation/arrow-back';
|
||||
|
||||
import MakePaymentDialog from './MakePaymentDialog/index';
|
||||
import CancelPaymentDialog from './CancelPaymentDialog/index';
|
||||
import moment from "moment";
|
||||
import get from 'lodash.get';
|
||||
import DC from 'decimal.js-light';
|
||||
import NumberFormat from 'react-number-format';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class OrderDetailComponent extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
value: 1,
|
||||
searchText: '',
|
||||
slideIndex: 0,
|
||||
tabSelected: 'gi',
|
||||
openModal: false
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.http = props.appstate.http;
|
||||
this.authStore = props.appstate.auth;
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
this.order = props.appstate.order;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.order.getDetail(this.props.match.params.id);
|
||||
}
|
||||
|
||||
handleUpdateInput = (searchText) => {
|
||||
this.setState({
|
||||
searchText: searchText,
|
||||
});
|
||||
};
|
||||
|
||||
handleNewRequest = () => {
|
||||
this.setState({
|
||||
searchText: '',
|
||||
});
|
||||
};
|
||||
|
||||
tabsHandleChange = (value) => {
|
||||
this.setState({
|
||||
slideIndex: value,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
handleChange = (tabSelected) => {
|
||||
this.setState({
|
||||
tabSelected: tabSelected,
|
||||
});
|
||||
// this.props.history.push(tabSelected);
|
||||
};
|
||||
|
||||
handleCloseModal = () => {
|
||||
this.setState({
|
||||
openModal: false
|
||||
})
|
||||
};
|
||||
|
||||
handleOpenModal = () => {
|
||||
this.setState({
|
||||
openModal: true
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
const customer = {
|
||||
name: 'Ridwan Abadi',
|
||||
identity_number: '98261536156313561',
|
||||
email: 'welove6215@einrot.com',
|
||||
address: 'Jalan Pramuka No. 81, Marga Jaya, Bekasi Selatan, Marga Jaya, Bekasi Sel., Kota Bks, Jawa Barat 17141',
|
||||
handphone: '081190876',
|
||||
phone: '0',
|
||||
place_birth: 'Jakarta',
|
||||
birth_date: moment().format('DD MMM YYYY'),
|
||||
gender: 'Male',
|
||||
tax_id: '98261536156313561',
|
||||
martial_status: 'Married'
|
||||
}
|
||||
|
||||
const order = {
|
||||
id: '467d6b50-ade0-4dd0-98ca-35cd083e16e0',
|
||||
order_id: 'book_461a1df5',
|
||||
package: 'The Exoticsm Of Minang',
|
||||
description: 'Feel the joy of wonderful world of exotic, culture, and outstanding view that will amaze you to the bone. Enjoy your holiday in very nice and peaceful place to clear your mind. With great hotel and profesional tour guide, we ensure you that you will have a unforgetable memories and happiness.\n',
|
||||
registered: moment(),
|
||||
detail_package: [
|
||||
{
|
||||
name: 'Destination',
|
||||
value: 'Bukittinggi, Minangkabau'
|
||||
},
|
||||
{
|
||||
name: 'Transport',
|
||||
value: 'Custom'
|
||||
},
|
||||
{
|
||||
name: 'Duration',
|
||||
value: '4 day 3 night'
|
||||
}
|
||||
],
|
||||
payment_type: 'Instalment',
|
||||
status: 'active'
|
||||
}
|
||||
|
||||
const totalPaid = get(this.order.selectedOrder, 'payments', [])
|
||||
.map(pay => (pay.type == 'cancel_payment') ? pay.amount = 0 : pay.amount)
|
||||
.reduce((total, v) => total.add(v), new DC(0));
|
||||
|
||||
const priceAfterDisc = get(this.order.selectedOrder, 'price_after_discount', 0);
|
||||
const disc = new DC(get(this.order.selectedOrder, 'price') || 0).minus(priceAfterDisc || 0);
|
||||
|
||||
const amountDue = new DC(priceAfterDisc || 0).minus(totalPaid);
|
||||
// const amountDue = new DC(0);
|
||||
|
||||
const actionsModals = [
|
||||
<FlatButton
|
||||
label="Cancel"
|
||||
primary={true}
|
||||
onClick={this.handleCloseModal}
|
||||
/>,
|
||||
<FlatButton
|
||||
label="Ok"
|
||||
primary={true}
|
||||
onClick={() => {
|
||||
this.order.payAirlineTicket().then((airlineTicket) => {
|
||||
this.order.setOrderStatus('ticketed');
|
||||
this.globalUI.openSnackbar('Payment success');
|
||||
});
|
||||
}}
|
||||
/>,
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="customerDetail containerMiddle animated fadeIn">
|
||||
<Dialog
|
||||
title="Are you sure that all data is correct?"
|
||||
actions={actionsModals}
|
||||
modal={true}
|
||||
open={this.state.openModal}
|
||||
>
|
||||
You will be charged
|
||||
</Dialog>
|
||||
|
||||
<div style={{marginBottom: '10px', marginLeft: '-15px'}}>
|
||||
<FlatButton
|
||||
className="headerMenu"
|
||||
inkBarStyle={{background: 'transparent'}}
|
||||
hoverColor="#f1f5f9"
|
||||
style={{background: '#ffffff00'}}
|
||||
onClick={() => this.props.history.goBack()}
|
||||
label="Back"
|
||||
primary={true}
|
||||
icon={<NavigationArrowBack />}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<MakePaymentDialog/>
|
||||
|
||||
<CancelPaymentDialog/>
|
||||
|
||||
<Card className="row">
|
||||
|
||||
<div className="flexSpaceBetween" style={{padding: 16}}>
|
||||
<div className="">
|
||||
<CardTitle style={{padding: 0, fontSize: 22}}
|
||||
titleStyle={{fontSize: 22}}
|
||||
title="Order Form"
|
||||
/>
|
||||
<div className="listCustDetail">
|
||||
<div className="listHeaderCustDetailItem flex">
|
||||
<p className="listHeaderCustomerDetailItemKey">Order Id</p>
|
||||
<p className="listHeaderCustomerDetailItemValue"><code>{this.order.selectedOrder.id}</code></p>
|
||||
</div>
|
||||
<div className="listHeaderCustDetailItem flex">
|
||||
<p className="listHeaderCustomerDetailItemKey">Order Date</p>
|
||||
<p className="listHeaderCustomerDetailItemValue">{moment(this.order.selectedOrder.created_at).format("DD MMMM YYYY, HH:mm:ss")}</p>
|
||||
</div>
|
||||
<div className="listHeaderCustDetailItem flex">
|
||||
<p className="listHeaderCustomerDetailItemKey">Payment Method</p>
|
||||
<p className="listHeaderCustomerDetailItemValue">{get(this.order.selectedOrder, 'paymentMethod.name', '-')}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ToolbarGroup>
|
||||
{
|
||||
this.order.orderDetail.type === 'packages' && this.order.orderDetail.status != 'canceled' && (<RaisedButton icon={<AddIcon/>} label="Make Payment" primary={true}
|
||||
onClick={() => this.globalUI.showDialog(DIALOG.ORDER.MAKE_PAYMENT)}/>)
|
||||
}
|
||||
{
|
||||
this.order.orderDetail.type === 'packages' && this.order.orderDetail.status != 'canceled' && (<RaisedButton icon={<RemoveIcon/>} label="Cancel Booking" primary={false}
|
||||
onClick={() => this.globalUI.showDialog(DIALOG.ORDER.CANCEL_PAYMENT)}/>)
|
||||
}
|
||||
{
|
||||
this.order.orderDetail.type === 'airline' && this.order.orderDetail.status === 'booked' &&
|
||||
(<RaisedButton icon={<AddIcon/>} label="Pay" primary={true}
|
||||
onClick={() => this.handleOpenModal()}/>)
|
||||
}
|
||||
{
|
||||
this.order.orderDetail.type === 'airline' && this.order.orderDetail.status === 'ticketed' &&
|
||||
(<RaisedButton icon={<AddIcon/>} label="Print Ticket" primary={true} onClick={() => this.globalUI.showDialog(DIALOG.ORDER.MAKE_PAYMENT)}/>)
|
||||
}{
|
||||
this.order.orderDetail.type === 'packages' && this.order.orderDetail.status == 'canceled' && (<p>This order is already Cancelled</p>)
|
||||
}
|
||||
</ToolbarGroup>
|
||||
</div>
|
||||
<Divider/>
|
||||
<CardHeader actAsExpander={true}
|
||||
showExpandableButton={false} style={{paddingBottom: 0}}
|
||||
subtitle={<a style={{fontSize: 12}}>CUSTOMER INFORMATION</a>}/>
|
||||
<CardText expandable={true} style={{paddingBottom: 0}}>
|
||||
<div className="row no-margin">
|
||||
<div className="col s12 m12 l6">
|
||||
<div className="listCustDetail">
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">Name</p>
|
||||
<p className="listCustomerDetailItemValue">{get(this.order.selectedOrder, 'customer.name', '-')}</p>
|
||||
</div>
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">Identity Number</p>
|
||||
<p className="listCustomerDetailItemValue">{get(this.order.selectedOrder, 'customer.passport_number', '-')}</p>
|
||||
</div>
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">Email</p>
|
||||
<p className="listCustomerDetailItemValue">{get(this.order.selectedOrder, 'customer.email', '-')}</p>
|
||||
</div>
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">Address</p>
|
||||
<p className="listCustomerDetailItemValue">{get(this.order.selectedOrder, 'customer.address', '-')}</p>
|
||||
</div>
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">Phone</p>
|
||||
<p
|
||||
className="listCustomerDetailItemValue">{get(this.order.selectedOrder, 'customer.phone_number', '-')}</p>
|
||||
</div>
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">Handphone</p>
|
||||
<p className="listCustomerDetailItemValue">-</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div className="col s12 m12 l6">
|
||||
<div className="listCustDetail">
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">Place & Birth Date</p>
|
||||
<p className="listCustomerDetailItemValue">{customer.place_birth}, {moment(get(this.order.selectedOrder, 'customer.date_of_birth', moment())).format("DD MMMM YYYY")}</p>
|
||||
</div>
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">Gender</p>
|
||||
<p className="listCustomerDetailItemValue">{get(this.order.selectedOrder, 'customer.gender', '-')}</p>
|
||||
</div>
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">Tax Id</p>
|
||||
<p className="listCustomerDetailItemValue">-</p>
|
||||
</div>
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">Martial Status</p>
|
||||
<p className="listCustomerDetailItemValue">-</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</CardText>
|
||||
|
||||
|
||||
<div style={{marginTop: 18}}>
|
||||
<Table selectable={false} className="TableOrder">
|
||||
<TableHeader displaySelectAll={false}
|
||||
adjustForCheckbox={false}
|
||||
enableSelectAll={false}>
|
||||
<TableRow style={{height: 38, background: '#f6f9fc'}}>
|
||||
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Package</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Description</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Price</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Amount</TableHeaderColumn>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody displayRowCheckbox={false}>
|
||||
<TableRow>
|
||||
<TableRowColumn>
|
||||
{get(this.order.selectedOrder, 'packageSchedule.package.name', '-')}
|
||||
<p style={{margin: '2px 0', fontSize: 10}}>
|
||||
Detail: <Link to={LINKS.SERVICE} target="_blank">View details</Link>
|
||||
</p>
|
||||
</TableRowColumn>
|
||||
<TableRowColumn>{get(this.order.selectedOrder, 'packageSchedule.package.description', '-')}</TableRowColumn>
|
||||
<TableRowColumn><NumberFormat value={get(this.order.selectedOrder, 'price', '0')} displayType={'text'} thousandSeparator={true} prefix={'IDR '}/></TableRowColumn>
|
||||
<TableRowColumn><NumberFormat value={get(this.order.selectedOrder, 'price_after_discount', '0')} displayType={'text'} thousandSeparator={true} prefix={'IDR '}/></TableRowColumn>
|
||||
</TableRow>
|
||||
|
||||
<TableRow displayBorder={false} className="TableRowCondensed TableRowCondensedFirst">
|
||||
<TableRowColumn colSpan={2} className="TableRowColumnCondensed TableRowColumnCondensedFirst"></TableRowColumn>
|
||||
<TableRowColumn className="align-right font-500 TableRowColumnCondensed TableRowColumnCondensedFirst">Subtotal</TableRowColumn>
|
||||
<TableRowColumn className="TableRowColumnCondensed TableRowColumnCondensedFirst"><NumberFormat value={get(this.order.selectedOrder, 'price_after_discount', '0')} displayType={'text'} thousandSeparator={true} prefix={'IDR '}/></TableRowColumn>
|
||||
</TableRow>
|
||||
<TableRow displayBorder={false} className="TableRowCondensed">
|
||||
<TableRowColumn colSpan={2} className="TableRowColumnCondensed"></TableRowColumn>
|
||||
<TableRowColumn className="align-right font-500 TableRowColumnCondensed">Discount</TableRowColumn>
|
||||
<TableRowColumn className="TableRowColumnCondensed"><NumberFormat value={disc.toString()} displayType={'text'} thousandSeparator={true} prefix={'IDR '}/></TableRowColumn>
|
||||
</TableRow>
|
||||
<TableRow displayBorder={false} className="TableRowCondensed">
|
||||
<TableRowColumn colSpan={2} className="TableRowColumnCondensed"></TableRowColumn>
|
||||
<TableRowColumn className="align-right font-500 TableRowColumnCondensed">Total</TableRowColumn>
|
||||
<TableRowColumn className="TableRowColumnCondensed"><NumberFormat value={get(this.order.selectedOrder, 'price_after_discount', '0')} displayType={'text'} thousandSeparator={true} prefix={'IDR '}/></TableRowColumn>
|
||||
</TableRow>
|
||||
<TableRow displayBorder={false} className="TableRowCondensed">
|
||||
<TableRowColumn colSpan={2} className="TableRowColumnCondensed"></TableRowColumn>
|
||||
<TableRowColumn className="align-right font-500 TableRowColumnCondensed">Total Paid</TableRowColumn>
|
||||
<TableRowColumn className="TableRowColumnCondensed"><NumberFormat value={totalPaid.toString()} displayType={'text'} thousandSeparator={true} prefix={'IDR '}/></TableRowColumn>
|
||||
</TableRow>
|
||||
<TableRow displayBorder={false} className="TableRowCondensed TableRowCondensedLast">
|
||||
<TableRowColumn colSpan={2} className="TableRowColumnCondensed TableRowColumnCondensedLast"></TableRowColumn>
|
||||
<TableRowColumn className="align-right font-500 TableRowColumnCondensed TableRowColumnCondensedLast">Amount
|
||||
Due </TableRowColumn>
|
||||
<TableRowColumn className="TableRowColumnCondensed TableRowColumnCondensedLast"><NumberFormat value={amountDue.toString()} displayType={'text'} thousandSeparator={true} prefix={'IDR '}/></TableRowColumn>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
<Divider/>
|
||||
</div>
|
||||
</Card>
|
||||
<Card>
|
||||
{/*<Toolbar className="toolbarCard" style={{backgroundColor: '#fff'}}>*/}
|
||||
{/*<ToolbarGroup>*/}
|
||||
{/*<ToolbarTitle actAsExpander={true}*/}
|
||||
{/*showExpandableButton={false} style={{fontSize: 14, fontWeight: 500, color: '#32325d', textTransform: 'capitalize'}}*/}
|
||||
{/*text={'Payments'}/>*/}
|
||||
{/*</ToolbarGroup>*/}
|
||||
|
||||
{/*</Toolbar>*/}
|
||||
|
||||
<CardHeader actAsExpander={true}
|
||||
showExpandableButton={false} style={{paddingBottom: 16}}
|
||||
subtitle={<a style={{fontSize: 12, paddingLeft: 10}}>Payments History</a>}/>
|
||||
<Divider/>
|
||||
|
||||
<CardText className="no-padding" expandable={true}>
|
||||
<Table selectable={false}>
|
||||
<TableHeader displaySelectAll={false}
|
||||
adjustForCheckbox={false}
|
||||
enableSelectAll={false}>
|
||||
<TableRow style={{height: 38, background: '#f6f9fc'}}>
|
||||
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Date</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Description</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Amount</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Status</TableHeaderColumn>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody displayRowCheckbox={false}>
|
||||
{get(this.order.selectedOrder, 'payments', []).map(pay => {
|
||||
return (
|
||||
<TableRow>
|
||||
<TableRowColumn>{moment(pay.created_at).format("DD MMMM YYYY, HH:mm:ss")}</TableRowColumn>
|
||||
<TableRowColumn>{pay.name}</TableRowColumn>
|
||||
<TableRowColumn><NumberFormat value={pay.amount} displayType={'text'} thousandSeparator={true} prefix={'IDR '}/></TableRowColumn>
|
||||
<TableRowColumn>{pay.status}</TableRowColumn>
|
||||
</TableRow>
|
||||
)
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</CardText>
|
||||
</Card>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
292
src/common/pages/CustomerDetail/OrderDetailAirlines/index.js
Normal file
292
src/common/pages/CustomerDetail/OrderDetailAirlines/index.js
Normal file
@@ -0,0 +1,292 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import {
|
||||
Card, CardTitle, CardText,
|
||||
Divider,
|
||||
MenuItem,
|
||||
FlatButton,
|
||||
RaisedButton,
|
||||
Table,
|
||||
TableBody,
|
||||
TableHeader,
|
||||
TableHeaderColumn,
|
||||
TableRow,
|
||||
TableRowColumn,
|
||||
TextField,
|
||||
Toolbar,
|
||||
ToolbarGroup,
|
||||
ToolbarSeparator, ToolbarTitle, CardHeader, Dialog,
|
||||
} from 'material-ui';
|
||||
import {Link} from 'react-router-dom';
|
||||
import {LINKS} from "../../../routes";
|
||||
import {DIALOG} from "../../../stores/global_ui";
|
||||
import AddIcon from 'material-ui/svg-icons/content/add';
|
||||
import NavigationArrowBack from 'material-ui/svg-icons/navigation/arrow-back';
|
||||
|
||||
import moment from "moment";
|
||||
import get from 'lodash.get';
|
||||
import DC from 'decimal.js-light';
|
||||
import NumberFormat from 'react-number-format';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class OrderDetailAirlinesComponent extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
value: 1,
|
||||
searchText: '',
|
||||
slideIndex: 0,
|
||||
tabSelected: 'gi',
|
||||
openModal: false
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.http = props.appstate.http;
|
||||
this.authStore = props.appstate.auth;
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
this.order = props.appstate.order;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.order.getAirlineDetail(this.props.match.params.id);
|
||||
}
|
||||
|
||||
handleUpdateInput = (searchText) => {
|
||||
this.setState({
|
||||
searchText: searchText,
|
||||
});
|
||||
};
|
||||
|
||||
handleNewRequest = () => {
|
||||
this.setState({
|
||||
searchText: '',
|
||||
});
|
||||
};
|
||||
|
||||
tabsHandleChange = (value) => {
|
||||
this.setState({
|
||||
slideIndex: value,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
handleChange = (tabSelected) => {
|
||||
this.setState({
|
||||
tabSelected: tabSelected,
|
||||
});
|
||||
// this.props.history.push(tabSelected);
|
||||
};
|
||||
|
||||
handleCloseModal = () => {
|
||||
this.setState({
|
||||
openModal: false
|
||||
})
|
||||
};
|
||||
|
||||
handleOpenModal = () => {
|
||||
this.setState({
|
||||
openModal: true
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
const customer = {
|
||||
name: 'Ridwan Abadi',
|
||||
identity_number: '98261536156313561',
|
||||
email: 'welove6215@einrot.com',
|
||||
address: 'Jalan Pramuka No. 81, Marga Jaya, Bekasi Selatan, Marga Jaya, Bekasi Sel., Kota Bks, Jawa Barat 17141',
|
||||
handphone: '081190876',
|
||||
phone: '0',
|
||||
place_birth: 'Jakarta',
|
||||
birth_date: moment().format('DD MMM YYYY'),
|
||||
gender: 'Male',
|
||||
tax_id: '98261536156313561',
|
||||
martial_status: 'Married'
|
||||
}
|
||||
|
||||
const order = {
|
||||
id: '467d6b50-ade0-4dd0-98ca-35cd083e16e0',
|
||||
order_id: 'book_461a1df5',
|
||||
package: 'The Exoticsm Of Minang',
|
||||
description: 'Feel the joy of wonderful world of exotic, culture, and outstanding view that will amaze you to the bone. Enjoy your holiday in very nice and peaceful place to clear your mind. With great hotel and profesional tour guide, we ensure you that you will have a unforgetable memories and happiness.\n',
|
||||
registered: moment(),
|
||||
detail_package: [
|
||||
{
|
||||
name: 'Destination',
|
||||
value: 'Bukittinggi, Minangkabau'
|
||||
},
|
||||
{
|
||||
name: 'Transport',
|
||||
value: 'Custom'
|
||||
},
|
||||
{
|
||||
name: 'Duration',
|
||||
value: '4 day 3 night'
|
||||
}
|
||||
],
|
||||
payment_type: 'Instalment',
|
||||
status: 'active'
|
||||
}
|
||||
|
||||
const totalPaid = get(this.order.selectedOrder, 'payments', [])
|
||||
.map(pay => pay.amount)
|
||||
.reduce((total, v) => total.add(v), new DC(0));
|
||||
|
||||
const priceAfterDisc = get(this.order.selectedOrder, 'price_after_discount', 0);
|
||||
const disc = new DC(get(this.order.selectedOrder, 'price') || 0).minus(priceAfterDisc || 0);
|
||||
|
||||
const amountDue = new DC(priceAfterDisc || 0).minus(totalPaid);
|
||||
|
||||
const actionsModals = [
|
||||
<FlatButton
|
||||
label="Cancel"
|
||||
primary={true}
|
||||
onClick={this.handleCloseModal}
|
||||
/>,
|
||||
<FlatButton
|
||||
label="Ok"
|
||||
primary={true}
|
||||
onClick={() => {
|
||||
this.order.payAirlineTicket().then((airlineTicket) => {
|
||||
this.order.setOrderStatus('ticketed');
|
||||
this.globalUI.openSnackbar('Payment success');
|
||||
});
|
||||
}}
|
||||
/>,
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="customerDetail containerMiddle animated fadeIn">
|
||||
<Dialog
|
||||
title="Are you sure that all data is correct?"
|
||||
actions={actionsModals}
|
||||
modal={true}
|
||||
open={this.state.openModal}
|
||||
>
|
||||
You will be charged
|
||||
</Dialog>
|
||||
|
||||
<div style={{marginBottom: '10px', marginLeft: '-15px'}}>
|
||||
<FlatButton
|
||||
className="headerMenu"
|
||||
inkBarStyle={{background: 'transparent'}}
|
||||
hoverColor="#f1f5f9"
|
||||
style={{background: '#ffffff00'}}
|
||||
onClick={() => this.props.history.goBack()}
|
||||
label="Back"
|
||||
primary={true}
|
||||
icon={<NavigationArrowBack />}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Card className="row">
|
||||
|
||||
<div className="flexSpaceBetween" style={{padding: 16}}>
|
||||
<div className="">
|
||||
<CardTitle style={{padding: 0, fontSize: 22}}
|
||||
titleStyle={{fontSize: 22}}
|
||||
title="Airlines Order Form"
|
||||
/>
|
||||
<div className="listCustDetail">
|
||||
<div className="listHeaderCustDetailItem flex">
|
||||
<p className="listHeaderCustomerDetailItemKey">PNR ID</p>
|
||||
<p className="listHeaderCustomerDetailItemValue"><code>{this.order.orderAirlineDetail.pnrid}</code></p>
|
||||
</div>
|
||||
<div className="listHeaderCustDetailItem flex">
|
||||
<p className="listHeaderCustomerDetailItemKey">Booking Code</p>
|
||||
<p className="listHeaderCustomerDetailItemValue">{this.order.orderAirlineDetail.retrieve.bookingcode}</p>
|
||||
</div>
|
||||
<div className="listHeaderCustDetailItem flex">
|
||||
<p className="listHeaderCustomerDetailItemKey">Status</p>
|
||||
<p className="listHeaderCustomerDetailItemValue">{this.order.orderAirlineDetail.retrieve.status}</p>
|
||||
</div>
|
||||
<div className="listHeaderCustDetailItem flex">
|
||||
<p className="listHeaderCustomerDetailItemKey">Time Limit</p>
|
||||
<p className="listHeaderCustomerDetailItemValue">{this.order.orderAirlineDetail.retrieve.timelimit}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ToolbarGroup>
|
||||
<RaisedButton icon={<AddIcon/>} label="Pay" primary={true}
|
||||
onClick={() => this.handleOpenModal()}/>
|
||||
</ToolbarGroup>
|
||||
</div>
|
||||
<Divider/>
|
||||
|
||||
<CardHeader actAsExpander={true}
|
||||
showExpandableButton={false} style={{paddingBottom: 0}}
|
||||
subtitle={<a style={{fontSize: 12}}>PASSENGER INFORMATION</a>}/>
|
||||
<div style={{marginTop: 18}}>
|
||||
<Table selectable={false} className="TableOrder">
|
||||
<TableHeader displaySelectAll={false}
|
||||
adjustForCheckbox={false}
|
||||
enableSelectAll={false}>
|
||||
<TableRow style={{height: 38, background: '#f6f9fc'}}>
|
||||
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>No. </TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Title</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Name</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Ticket No</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Date of Birth</TableHeaderColumn>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody displayRowCheckbox={false}>
|
||||
{this.order.orderAirlineDetail.retrieve.pax.map(pax => {
|
||||
return (<TableRow>
|
||||
<TableRowColumn>{pax.paxno}</TableRowColumn>
|
||||
<TableRowColumn>{pax.title}</TableRowColumn>
|
||||
<TableRowColumn>{pax.name}</TableRowColumn>
|
||||
<TableRowColumn>{pax.ticketno}</TableRowColumn>
|
||||
<TableRowColumn>{pax.dob}</TableRowColumn>
|
||||
</TableRow>)
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
<Divider/>
|
||||
</div>
|
||||
|
||||
<Divider/>
|
||||
|
||||
<CardHeader actAsExpander={true}
|
||||
showExpandableButton={false} style={{paddingBottom: 0}}
|
||||
subtitle={<a style={{fontSize: 12}}>PAX CONTACT INFORMATION</a>}/>
|
||||
<div style={{marginTop: 18}}>
|
||||
<Table selectable={false} className="TableOrder">
|
||||
<TableHeader displaySelectAll={false}
|
||||
adjustForCheckbox={false}
|
||||
enableSelectAll={false}>
|
||||
<TableRow style={{height: 38, background: '#f6f9fc'}}>
|
||||
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>First Name</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Last Name</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Phone 1</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Phone 2</TableHeaderColumn>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody displayRowCheckbox={false}>
|
||||
<TableRow>
|
||||
<TableRowColumn>{this.order.orderAirlineDetail.retrieve.paxcontact.firstname}</TableRowColumn>
|
||||
<TableRowColumn>{this.order.orderAirlineDetail.retrieve.paxcontact.lastname}</TableRowColumn>
|
||||
<TableRowColumn>{this.order.orderAirlineDetail.retrieve.paxcontact.phone1}</TableRowColumn>
|
||||
<TableRowColumn>{this.order.orderAirlineDetail.retrieve.paxcontact.phone2}</TableRowColumn>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
<Divider/>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
171
src/common/pages/CustomerDetail/Wallet/index.js
Normal file
171
src/common/pages/CustomerDetail/Wallet/index.js
Normal file
@@ -0,0 +1,171 @@
|
||||
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,
|
||||
Tabs, Tab,
|
||||
RaisedButton,
|
||||
Toolbar,
|
||||
DatePicker,
|
||||
FontIcon,
|
||||
Table,
|
||||
TableBody,
|
||||
TableHeader,
|
||||
TableHeaderColumn,
|
||||
TableRow,
|
||||
TableRowColumn,
|
||||
MenuItem,
|
||||
ToolbarGroup,
|
||||
FloatingActionButton,
|
||||
ToolbarSeparator,
|
||||
IconButton,
|
||||
ToolbarTitle,
|
||||
RadioButton,
|
||||
TextField,
|
||||
Paper,
|
||||
RadioButtonGroup
|
||||
} from 'material-ui';
|
||||
import {LINKS} from "../../../routes";
|
||||
import {Link} from 'react-router-dom';
|
||||
import StarBorder from 'material-ui/svg-icons/toggle/star-border';
|
||||
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 '../style.scss';
|
||||
import {appConfig} from "../../../config/app";
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class WalletCustomer extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
value: 1,
|
||||
searchText: '',
|
||||
slideIndex: 0
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.http = props.appstate.http;
|
||||
this.authStore = props.appstate.auth;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
console.log('Profile loaded!');
|
||||
|
||||
}
|
||||
|
||||
handleUpdateInput = (searchText) => {
|
||||
this.setState({
|
||||
searchText: searchText,
|
||||
});
|
||||
};
|
||||
|
||||
handleNewRequest = () => {
|
||||
this.setState({
|
||||
searchText: '',
|
||||
});
|
||||
};
|
||||
|
||||
tabsHandleChange = (value) => {
|
||||
this.setState({
|
||||
slideIndex: value,
|
||||
});
|
||||
};
|
||||
|
||||
handleChange = (event, index, value) => this.setState({value});
|
||||
|
||||
render() {
|
||||
const styles = {
|
||||
|
||||
radioButton: {
|
||||
marginBottom: 16,
|
||||
},
|
||||
};
|
||||
|
||||
const colors = [
|
||||
'Jakarta - Soekarno - Hatta (CGK)',
|
||||
'Bali',
|
||||
'Surabaya',
|
||||
'Yogyakarta',
|
||||
'Aceh',
|
||||
'Kalimantan',
|
||||
'Medan',
|
||||
'Papua',
|
||||
];
|
||||
|
||||
const items = [
|
||||
<MenuItem key={1} value={1} primaryText="All Maskapai"/>,
|
||||
<MenuItem key={2} value={2} primaryText="Air Asia"/>,
|
||||
<MenuItem key={3} value={3} primaryText="Weeknights"/>,
|
||||
<MenuItem key={4} value={4} primaryText="Weekends"/>,
|
||||
<MenuItem key={5} value={5} primaryText="Weekly"/>,
|
||||
];
|
||||
|
||||
const count = [
|
||||
<MenuItem key={1} value={1} primaryText="1"/>,
|
||||
<MenuItem key={2} value={2} primaryText="2"/>,
|
||||
<MenuItem key={3} value={3} primaryText="3"/>,
|
||||
<MenuItem key={4} value={4} primaryText="4"/>,
|
||||
<MenuItem key={5} value={5} primaryText="5"/>,
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="">
|
||||
<Card>
|
||||
<Toolbar className="toolbarCard" style={{backgroundColor: '#fff'}}>
|
||||
<ToolbarGroup>
|
||||
<SearchIcon style={{marginRight: 8, color: "#999"}}/>
|
||||
<TextField
|
||||
hintText="Search Transaction"
|
||||
style={{fontSize: 14}}
|
||||
hintStyle={{fontSize: 14}}
|
||||
underlineShow={false}
|
||||
/>
|
||||
</ToolbarGroup>
|
||||
</Toolbar>
|
||||
<Divider/>
|
||||
<div>
|
||||
<Table selectable={false}>
|
||||
<TableHeader displaySelectAll={false}
|
||||
adjustForCheckbox={false}
|
||||
enableSelectAll={false}>
|
||||
<TableRow style={{height: 38, background: '#f6f9fc'}}>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun" style={{height: 'auto'}}>Id</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun" style={{height: 'auto'}}>Date</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun" style={{height: 'auto'}}>Tyoe</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Status</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Amount</TableHeaderColumn>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody displayRowCheckbox={false}>
|
||||
<TableRow>
|
||||
<TableRowColumn><Link to={`${LINKS.CUSTOMER}/1827381/wallet/1827381`}
|
||||
key={1827381}>#1827381</Link></TableRowColumn>
|
||||
<TableRowColumn>12/02/2017 20:10:30</TableRowColumn>
|
||||
<TableRowColumn>Package Down Payment</TableRowColumn>
|
||||
<TableRowColumn style={{color: "green"}}>Approved</TableRowColumn>
|
||||
<TableRowColumn>3.000.000</TableRowColumn>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
|
||||
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
374
src/common/pages/CustomerDetail/WalletDetail/index.js
Normal file
374
src/common/pages/CustomerDetail/WalletDetail/index.js
Normal file
@@ -0,0 +1,374 @@
|
||||
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,
|
||||
Tabs, Tab,
|
||||
RaisedButton,
|
||||
Toolbar,
|
||||
DatePicker,
|
||||
FontIcon,
|
||||
Table,
|
||||
TableBody,
|
||||
TableHeader,
|
||||
TableHeaderColumn,
|
||||
TableRow,
|
||||
TableRowColumn,
|
||||
MenuItem,
|
||||
ToolbarGroup,
|
||||
FloatingActionButton,
|
||||
ToolbarSeparator,
|
||||
IconButton,
|
||||
ToolbarTitle,
|
||||
RadioButton,
|
||||
TextField,
|
||||
Paper,
|
||||
RadioButtonGroup
|
||||
} from 'material-ui';
|
||||
import StarBorder from 'material-ui/svg-icons/toggle/star-border';
|
||||
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 NavigationArrowBack from 'material-ui/svg-icons/navigation/arrow-back';
|
||||
import NavigationCancel from 'material-ui/svg-icons/navigation/cancel';
|
||||
import CommunicationNoSim from 'material-ui/svg-icons/communication/no-sim';
|
||||
|
||||
import '../style.scss';
|
||||
import {appConfig} from "../../../config/app";
|
||||
import {DIALOG} from "../../../stores/global_ui";
|
||||
import {LINKS} from "../../../routes";
|
||||
import {Link} from "react-router-dom";
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class WalletCustomerDetail extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
value: 1,
|
||||
searchText: '',
|
||||
slideIndex: 0
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.http = props.appstate.http;
|
||||
this.authStore = props.appstate.auth;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
console.log('Profile loaded!');
|
||||
|
||||
}
|
||||
|
||||
handleUpdateInput = (searchText) => {
|
||||
this.setState({
|
||||
searchText: searchText,
|
||||
});
|
||||
};
|
||||
|
||||
handleNewRequest = () => {
|
||||
this.setState({
|
||||
searchText: '',
|
||||
});
|
||||
};
|
||||
|
||||
tabsHandleChange = (value) => {
|
||||
this.setState({
|
||||
slideIndex: value,
|
||||
});
|
||||
};
|
||||
|
||||
handleChange = (event, index, value) => this.setState({value});
|
||||
|
||||
render() {
|
||||
const styles = {
|
||||
|
||||
radioButton: {
|
||||
marginBottom: 16,
|
||||
},
|
||||
};
|
||||
|
||||
const colors = [
|
||||
'Jakarta - Soekarno - Hatta (CGK)',
|
||||
'Bali',
|
||||
'Surabaya',
|
||||
'Yogyakarta',
|
||||
'Aceh',
|
||||
'Kalimantan',
|
||||
'Medan',
|
||||
'Papua',
|
||||
];
|
||||
|
||||
const items = [
|
||||
<MenuItem key={1} value={1} primaryText="All Maskapai"/>,
|
||||
<MenuItem key={2} value={2} primaryText="Air Asia"/>,
|
||||
<MenuItem key={3} value={3} primaryText="Weeknights"/>,
|
||||
<MenuItem key={4} value={4} primaryText="Weekends"/>,
|
||||
<MenuItem key={5} value={5} primaryText="Weekly"/>,
|
||||
];
|
||||
|
||||
const count = [
|
||||
<MenuItem key={1} value={1} primaryText="1"/>,
|
||||
<MenuItem key={2} value={2} primaryText="2"/>,
|
||||
<MenuItem key={3} value={3} primaryText="3"/>,
|
||||
<MenuItem key={4} value={4} primaryText="4"/>,
|
||||
<MenuItem key={5} value={5} primaryText="5"/>,
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="customerDetail containerMiddle animated fadeIn">
|
||||
<div style={{marginBottom: '10px', marginLeft: '-15px'}}>
|
||||
<FlatButton
|
||||
className="headerMenu"
|
||||
inkBarStyle={{background: 'transparent'}}
|
||||
hoverColor="#f1f5f9"
|
||||
style={{background: '#ffffff00'}}
|
||||
onClick={() => this.props.history.goBack()}
|
||||
label="Back"
|
||||
primary={true}
|
||||
icon={<NavigationArrowBack/>}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Card className="row">
|
||||
|
||||
<div className="flexSpaceBetween" style={{padding: 16}}>
|
||||
<div className="">
|
||||
<CardTitle style={{padding: 0, fontSize: 22}}
|
||||
titleStyle={{fontSize: 22}}
|
||||
title="Transaction #1827381"
|
||||
/>
|
||||
<div className="listCustDetail">
|
||||
<div className="listHeaderCustDetailItem flex">
|
||||
<p className="listHeaderCustomerDetailItemKey">Type</p>
|
||||
<p className="listHeaderCustomerDetailItemValue"><code>Package Down Payment</code></p>
|
||||
</div>
|
||||
<div className="listHeaderCustDetailItem flex">
|
||||
<p className="listHeaderCustomerDetailItemKey">Date</p>
|
||||
<p className="listHeaderCustomerDetailItemValue">10 October 2017</p>
|
||||
</div>
|
||||
<div className="listHeaderCustDetailItem flex">
|
||||
<p className="listHeaderCustomerDetailItemKey">To</p>
|
||||
<p className="listHeaderCustomerDetailItemValue">Agent #6767567</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ToolbarGroup>
|
||||
<IconButton tooltip="Cancel">
|
||||
<NavigationCancel />
|
||||
</IconButton>
|
||||
<IconButton tooltip="Void">
|
||||
<CommunicationNoSim />
|
||||
</IconButton>
|
||||
</ToolbarGroup>
|
||||
</div>
|
||||
<Divider/>
|
||||
{/*<CardHeader actAsExpander={true}*/}
|
||||
{/*showExpandableButton={false} style={{paddingBottom: 0}}*/}
|
||||
{/*subtitle={<a style={{fontSize: 12}}>CUSTOMER INFORMATION</a>}/>*/}
|
||||
{/*<CardText expandable={true} style={{paddingBottom:0}}>*/}
|
||||
{/*<div className="row no-margin">*/}
|
||||
{/*<div className="col l6">*/}
|
||||
{/*<div className="listCustDetail">*/}
|
||||
{/*<div className="listCustDetailItem flex">*/}
|
||||
{/*<p className="listCustomerDetailItemKey">Name</p>*/}
|
||||
{/*<p className="listCustomerDetailItemValue"></p>*/}
|
||||
{/*</div>*/}
|
||||
{/*<div className="listCustDetailItem flex">*/}
|
||||
{/*<p className="listCustomerDetailItemKey">Identity Number</p>*/}
|
||||
{/*<p className="listCustomerDetailItemValue"></p>*/}
|
||||
{/*</div>*/}
|
||||
{/*<div className="listCustDetailItem flex">*/}
|
||||
{/*<p className="listCustomerDetailItemKey">Email</p>*/}
|
||||
{/*<p className="listCustomerDetailItemValue"></p>*/}
|
||||
{/*</div>*/}
|
||||
{/*<div className="listCustDetailItem flex">*/}
|
||||
{/*<p className="listCustomerDetailItemKey">Address</p>*/}
|
||||
{/*<p className="listCustomerDetailItemValue"></p>*/}
|
||||
{/*</div>*/}
|
||||
{/*<div className="listCustDetailItem flex">*/}
|
||||
{/*<p className="listCustomerDetailItemKey">Phone</p>*/}
|
||||
{/*<p*/}
|
||||
{/*className="listCustomerDetailItemValue"></p>*/}
|
||||
{/*</div>*/}
|
||||
{/*<div className="listCustDetailItem flex">*/}
|
||||
{/*<p className="listCustomerDetailItemKey">Handphone</p>*/}
|
||||
{/*<p className="listCustomerDetailItemValue"></p>*/}
|
||||
{/*</div>*/}
|
||||
|
||||
{/*</div>*/}
|
||||
|
||||
{/*</div>*/}
|
||||
|
||||
{/*<div className="col l6">*/}
|
||||
{/*<div className="listCustDetail">*/}
|
||||
{/*<div className="listCustDetailItem flex">*/}
|
||||
{/*<p className="listCustomerDetailItemKey">Place & Birth Date</p>*/}
|
||||
{/*<p className="listCustomerDetailItemValue">, </p>*/}
|
||||
{/*</div>*/}
|
||||
{/*<div className="listCustDetailItem flex">*/}
|
||||
{/*<p className="listCustomerDetailItemKey">Gender</p>*/}
|
||||
{/*<p className="listCustomerDetailItemValue"></p>*/}
|
||||
{/*</div>*/}
|
||||
{/*<div className="listCustDetailItem flex">*/}
|
||||
{/*<p className="listCustomerDetailItemKey">Tax Id</p>*/}
|
||||
{/*<p className="listCustomerDetailItemValue"></p>*/}
|
||||
{/*</div>*/}
|
||||
{/*<div className="listCustDetailItem flex">*/}
|
||||
{/*<p className="listCustomerDetailItemKey">Martial Status</p>*/}
|
||||
{/*<p className="listCustomerDetailItemValue"></p>*/}
|
||||
{/*</div>*/}
|
||||
{/*</div>*/}
|
||||
|
||||
{/*</div>*/}
|
||||
|
||||
{/*</div>*/}
|
||||
{/*</CardText>*/}
|
||||
|
||||
|
||||
<div style={{marginTop: 0}}>
|
||||
<Table selectable={false}>
|
||||
<TableHeader displaySelectAll={false}
|
||||
adjustForCheckbox={false}
|
||||
enableSelectAll={false}>
|
||||
<TableRow style={{height: 38, background: '#f6f9fc'}}>
|
||||
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Description</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Qty</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Price</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Discount</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Amount</TableHeaderColumn>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody displayRowCheckbox={false}>
|
||||
|
||||
<TableRow>
|
||||
<TableRowColumn>Package #92839 Payment</TableRowColumn>
|
||||
<TableRowColumn>1</TableRowColumn>
|
||||
<TableRowColumn>2.000.000</TableRowColumn>
|
||||
<TableRowColumn>500.000</TableRowColumn>
|
||||
<TableRowColumn>1.500.000</TableRowColumn>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableRowColumn>Package #92839 Payment</TableRowColumn>
|
||||
<TableRowColumn>1</TableRowColumn>
|
||||
<TableRowColumn>2.000.000</TableRowColumn>
|
||||
<TableRowColumn>500.000</TableRowColumn>
|
||||
<TableRowColumn>1.500.000</TableRowColumn>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableRowColumn></TableRowColumn>
|
||||
<TableRowColumn></TableRowColumn>
|
||||
<TableRowColumn></TableRowColumn>
|
||||
<TableRowColumn><b>Total</b></TableRowColumn>
|
||||
<TableRowColumn><b>3.000.000</b></TableRowColumn>
|
||||
</TableRow>
|
||||
|
||||
{/*<TableRow>*/}
|
||||
{/*<TableRowColumn><p style={{margin:'2px 0', fontSize:10}}>Detail: <Link to={LINKS.SERVICE} target="_blank">View details</Link></p>*/}
|
||||
{/*{order.detail_package.map((deta) => {*/}
|
||||
{/*return (*/}
|
||||
{/*<p key={deta.name}>{deta.name} - {deta.value}</p>*/}
|
||||
{/*)*/}
|
||||
{/*})}*/}
|
||||
|
||||
{/*</TableRowColumn>*/}
|
||||
{/*<TableRowColumn></TableRowColumn>*/}
|
||||
{/*<TableRowColumn>Rp. 19.000.000.00</TableRowColumn>*/}
|
||||
{/*<TableRowColumn>Rp. 19.000.000.00</TableRowColumn>*/}
|
||||
{/*</TableRow>*/}
|
||||
{/*<TableRow>*/}
|
||||
{/*<TableRowColumn colSpan={2} ></TableRowColumn>*/}
|
||||
{/*<TableRowColumn className="align-right" >Subtotal</TableRowColumn>*/}
|
||||
{/*<TableRowColumn>Rp. 19.000.000.00</TableRowColumn>*/}
|
||||
{/*</TableRow>*/}
|
||||
{/*<TableRow>*/}
|
||||
{/*<TableRowColumn>Discount</TableRowColumn>*/}
|
||||
{/*<TableRowColumn>0.00</TableRowColumn>*/}
|
||||
{/*</TableRow>*/}
|
||||
{/*<TableRow>*/}
|
||||
{/*<TableRowColumn>Total (IDR)</TableRowColumn>*/}
|
||||
{/*<TableRowColumn>Rp. 19.000.000.00</TableRowColumn>*/}
|
||||
{/*</TableRow>*/}
|
||||
{/*<TableRow>*/}
|
||||
{/*<TableRowColumn>Total Paid (IDR)</TableRowColumn>*/}
|
||||
{/*<TableRowColumn>0.00</TableRowColumn>*/}
|
||||
{/*</TableRow>*/}
|
||||
{/*<TableRow>*/}
|
||||
{/*<TableRowColumn>Amount Due (IDR)</TableRowColumn>*/}
|
||||
{/*<TableRowColumn>Rp. 19.000.000.00</TableRowColumn>*/}
|
||||
{/*</TableRow>*/}
|
||||
</TableBody>
|
||||
</Table>
|
||||
<Divider/>
|
||||
|
||||
</div>
|
||||
</Card>
|
||||
<Card>
|
||||
{/*<Toolbar className="toolbarCard" style={{backgroundColor: '#fff'}}>*/}
|
||||
{/*<ToolbarGroup>*/}
|
||||
{/*<ToolbarTitle actAsExpander={true}*/}
|
||||
{/*showExpandableButton={false} style={{fontSize: 14, fontWeight: 500, color: '#32325d', textTransform: 'capitalize'}}*/}
|
||||
{/*text={'Payments'}/>*/}
|
||||
{/*</ToolbarGroup>*/}
|
||||
|
||||
{/*</Toolbar>*/}
|
||||
|
||||
<CardHeader actAsExpander={true}
|
||||
showExpandableButton={false} style={{paddingBottom: 16}}
|
||||
subtitle={<a style={{fontSize: 12, paddingLeft: 10}}>Transaction History</a>}/>
|
||||
<Divider/>
|
||||
|
||||
<CardText className="no-padding" expandable={true}>
|
||||
<Table selectable={false}>
|
||||
<TableHeader displaySelectAll={false}
|
||||
adjustForCheckbox={false}
|
||||
enableSelectAll={false}>
|
||||
<TableRow style={{height: 38, background: '#f6f9fc'}}>
|
||||
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Date</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Description</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Amount</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Status</TableHeaderColumn>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody displayRowCheckbox={false}>
|
||||
<TableRow>
|
||||
<TableRowColumn>10/02/2017 22:30:10</TableRowColumn>
|
||||
<TableRowColumn>Awaiting Approval</TableRowColumn>
|
||||
<TableRowColumn>Rp. 3.000.000.00</TableRowColumn>
|
||||
<TableRowColumn>Approved</TableRowColumn>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableRowColumn>10/02/2017 20:30:10</TableRowColumn>
|
||||
<TableRowColumn>Awaiting Approval</TableRowColumn>
|
||||
<TableRowColumn>Rp. 3.000.000.00</TableRowColumn>
|
||||
<TableRowColumn>Pending</TableRowColumn>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</CardText>
|
||||
</Card>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
88
src/common/pages/CustomerDetail/index.js
Normal file
88
src/common/pages/CustomerDetail/index.js
Normal file
@@ -0,0 +1,88 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import {FlatButton, Tab, Tabs} from "material-ui";
|
||||
import GeneralInformation from "./GeneralInformation/index";
|
||||
import CustomerOrder from "./Order/index";
|
||||
import WalletCustomer from "./Wallet/index";
|
||||
import {
|
||||
Card,
|
||||
Divider
|
||||
} from 'material-ui';
|
||||
import {Link} from 'react-router-dom';
|
||||
import {LINKS} from "../../routes";
|
||||
import './style.scss'
|
||||
import NavigationArrowBack from 'material-ui/svg-icons/navigation/arrow-back';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class CustomerDetail extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
tabSelected: 'gi',
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.customer = props.appstate.customer;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
console.log(this.props);
|
||||
this.customer.selectedCustomer = {
|
||||
id : this.props.match.params.id
|
||||
}
|
||||
this.customer.getDetail(this.props.match.params.id);
|
||||
}
|
||||
|
||||
handleChange = (tabSelected) => {
|
||||
this.setState({
|
||||
tabSelected: tabSelected,
|
||||
});
|
||||
// this.props.history.push(tabSelected);
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="customerDetail containerMiddle animated fadeIn">
|
||||
<div style={{marginBottom: '10px', marginLeft: '-15px'}}>
|
||||
<FlatButton
|
||||
className="headerMenu"
|
||||
hoverColor="#f1f5f9"
|
||||
style={{background: '#ffffff00'}}
|
||||
onClick={() => this.props.history.goBack()}
|
||||
label="Back"
|
||||
primary={true}
|
||||
icon={<NavigationArrowBack />}
|
||||
/>
|
||||
{/*<h3 className="headerMenu"><Link to={LINKS.CUSTOMER}>Customers</Link></h3>*/}
|
||||
</div>
|
||||
|
||||
<Divider style={{marginBottom: 20, marginTop: 15}} />
|
||||
<div className="row">
|
||||
<Tabs
|
||||
value={this.state.tabSelected}
|
||||
onChange={this.handleChange}
|
||||
inkBarStyle={{background: 'transparent'}}
|
||||
className="tabsAkun"
|
||||
style={{background: '#ffffff00'}}>
|
||||
<Tab
|
||||
label="General"
|
||||
value="gi"
|
||||
className={(this.state.tabSelected === 'gi') ? "buttonTabs buttonTabsActive" : 'buttonTabs'}>
|
||||
{this.state.tabSelected === 'gi' && <GeneralInformation/>}
|
||||
</Tab>
|
||||
<Tab label="Order" value="order"
|
||||
className={(this.state.tabSelected === 'order') ? "buttonTabs buttonTabsActive" : 'buttonTabs'}>
|
||||
{(this.state.tabSelected === 'order' && <CustomerOrder history={this.props.history}/>)}
|
||||
</Tab>
|
||||
<Tab label="Wallet" value="wallet"
|
||||
className={(this.state.tabSelected === 'wallet') ? "buttonTabs buttonTabsActive" : 'buttonTabs'}>
|
||||
{(this.state.tabSelected === 'wallet') && <WalletCustomer/>}
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
50
src/common/pages/CustomerDetail/style.scss
Normal file
50
src/common/pages/CustomerDetail/style.scss
Normal file
@@ -0,0 +1,50 @@
|
||||
.customerDetail {
|
||||
margin-top: 35px;
|
||||
.listCustomerDetailItemKey {
|
||||
flex: 0 0 180px;
|
||||
color: #6b7c93;
|
||||
font-size: 12px;
|
||||
line-height: 1.6;
|
||||
padding: 2px 0 2px 0;
|
||||
}
|
||||
.listCustomerDetailItemValue {
|
||||
flex: 1 1 auto;
|
||||
font-size: 12px;
|
||||
color: #32325d;
|
||||
line-height: 1.6;
|
||||
padding: 2px 0 2px 0;
|
||||
font-weight: 300;
|
||||
|
||||
}
|
||||
|
||||
.listCustDetailItem code {
|
||||
color: #32325d;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
|
||||
}
|
||||
|
||||
.listHeaderCustomerDetailItemKey {
|
||||
flex: 0 0 180px;
|
||||
color: #6b7c93;
|
||||
line-height: 1.6;
|
||||
font-size: 12px;
|
||||
}
|
||||
.listHeaderCustomerDetailItemValue {
|
||||
flex: 0 0 180px;
|
||||
font-size: 12px;
|
||||
color: #32325d;
|
||||
line-height: 1.6;
|
||||
font-weight: 400;
|
||||
|
||||
}
|
||||
|
||||
.listHeaderCustDetailItem code {
|
||||
color: #32325d;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
310
src/common/pages/Customers/CustomerDialog/CustomerDetailForm.js
Normal file
310
src/common/pages/Customers/CustomerDialog/CustomerDetailForm.js
Normal file
@@ -0,0 +1,310 @@
|
||||
import React from 'react';
|
||||
import {inject, observer} from 'mobx-react';
|
||||
import {DatePicker, MenuItem, SelectField, TextField,} from 'material-ui';
|
||||
|
||||
// import '../../Service/style.scss';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class CustomerDetailForm extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.customer = props.appstate.customer;
|
||||
this.state = {
|
||||
gender : 0,
|
||||
name: '',
|
||||
email: '',
|
||||
date_of_birth: '',
|
||||
address: '',
|
||||
occupation: '',
|
||||
passport_number: '',
|
||||
marital:0,
|
||||
id_type : null,
|
||||
error_email : '',
|
||||
...props.defaultValue
|
||||
};
|
||||
this.http = props.appstate.http;
|
||||
this.authStore = props.appstate.auth;
|
||||
}
|
||||
|
||||
handleChangeName = (event) =>{
|
||||
this.customer.CustomerData.name = event.target.value;
|
||||
};
|
||||
|
||||
handleChangeEmail = (event) =>{
|
||||
var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||
if(!re.test(event.target.value)){
|
||||
this.customer.CustomerData.error_email ='Email format not valid';
|
||||
this.setState({
|
||||
error_email :'Email format not valid'
|
||||
})
|
||||
}
|
||||
else{
|
||||
this.customer.CustomerData.error_email ='';
|
||||
this.setState({
|
||||
error_email :''
|
||||
})
|
||||
}
|
||||
this.customer.CustomerData.email = event.target.value;
|
||||
};
|
||||
|
||||
handleChangeDate = (event, value) =>{
|
||||
this.customer.CustomerData.date_of_birth = value;
|
||||
};
|
||||
|
||||
handleChangeGender = (event, index, value) =>{
|
||||
this.setState({gender: value});
|
||||
this.customer.CustomerData.gender = value;
|
||||
};
|
||||
|
||||
handleChangePassport = (event) =>{
|
||||
this.customer.CustomerData.passport_number = event.target.value;
|
||||
};
|
||||
|
||||
handleChangeOccupation = (event) =>{
|
||||
this.customer.CustomerData.occupation = event.target.value;
|
||||
};
|
||||
|
||||
handleChangeAddress = (event) =>{
|
||||
this.customer.CustomerData.address = event.target.value;
|
||||
};
|
||||
|
||||
handleChangeBirthPlace = (event) =>{
|
||||
this.customer.CustomerData.birth_place = event.target.value;
|
||||
};
|
||||
|
||||
handleChangePhone = (event) =>{
|
||||
this.customer.CustomerData.phone = event.target.value;
|
||||
};
|
||||
|
||||
handleChangeHandphone = (event) =>{
|
||||
this.customer.CustomerData.handphone = event.target.value;
|
||||
};
|
||||
|
||||
handleChangeMarital = (event, index, value) =>{
|
||||
this.setState({marital:value})
|
||||
this.customer.CustomerData.martial_status = value;
|
||||
};
|
||||
|
||||
handleChangeTaxNumber = (event) =>{
|
||||
this.customer.CustomerData.id_tax_number = event.target.value;
|
||||
};
|
||||
|
||||
handleChangeType = (event,index,value) =>{
|
||||
this.setState({
|
||||
id_type : value
|
||||
})
|
||||
this.customer.CustomerData.id_type = value;
|
||||
};
|
||||
|
||||
handleChangeNumber= (event) =>{
|
||||
this.customer.CustomerData.id_number = event.target.value;
|
||||
};
|
||||
|
||||
render() {
|
||||
|
||||
const gender = [
|
||||
<MenuItem key={1} value={"Man"} primaryText="Man"/>,
|
||||
<MenuItem key={2} value={"Woman"} primaryText="Woman"/>,
|
||||
];
|
||||
|
||||
const marital_status = [
|
||||
<MenuItem key={1} value={"Married"} primaryText="Married"/>,
|
||||
<MenuItem key={2} value={"Single"} primaryText="Single"/>,
|
||||
<MenuItem key={2} value={"Divorced"} primaryText="Divorced"/>,
|
||||
<MenuItem key={2} value={"Widowed"} primaryText="Widowed"/>,
|
||||
];
|
||||
|
||||
const id_type = [
|
||||
<MenuItem key={1} value={"Resident ID Card"} primaryText="Resident ID Card"/>,
|
||||
<MenuItem key={2} value={"Driving Lisence"} primaryText="Driving Lisence"/>,
|
||||
];
|
||||
|
||||
return(
|
||||
<div style={{
|
||||
paddingTop: 10
|
||||
}}>
|
||||
<div className="row">
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Name</p>
|
||||
<TextField
|
||||
fullWidth={true}
|
||||
onChange={this.handleChangeName}
|
||||
hintText="E.g. Michael Jordan"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Email</p>
|
||||
<TextField
|
||||
fullWidth={true}
|
||||
onChange={this.handleChangeEmail}
|
||||
type="email"
|
||||
hintText="E.g. Michael.Jordan@domain.com"
|
||||
errorText={this.state.error_email}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Date of Birth</p>
|
||||
<DatePicker
|
||||
fullWidth={true}
|
||||
mode="landscape"
|
||||
onChange={this.handleChangeDate}
|
||||
hintText="2017-08-17"
|
||||
openToYearSelection={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Gender</p>
|
||||
<SelectField
|
||||
value={this.state.gender}
|
||||
onChange={this.handleChangeGender}
|
||||
fullWidth={true}
|
||||
>
|
||||
{gender}
|
||||
</SelectField>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Passport Number</p>
|
||||
<TextField
|
||||
hintText="E.g. X000000"
|
||||
onChange={this.handleChangePassport}
|
||||
fullWidth={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Occupation</p>
|
||||
<TextField
|
||||
hintText="E.g. PNS"
|
||||
onChange={this.handleChangeOccupation}
|
||||
fullWidth={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Address</p>
|
||||
<TextField
|
||||
hintText="E.g. Jl. Kemanggisan No.25 Jakarta Barat"
|
||||
multiLine={true}
|
||||
fullWidth={true}
|
||||
rows={1}
|
||||
rowsMax={4}
|
||||
onChange={this.handleChangeAddress}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Birth Place</p>
|
||||
<TextField
|
||||
hintText="E.g. Bandung"
|
||||
fullWidth={true}
|
||||
onChange={this.handleChangeBirthPlace}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Phone</p>
|
||||
<TextField
|
||||
hintText="E.g. 88954361"
|
||||
onChange={this.handleChangePhone}
|
||||
fullWidth={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Handphone</p>
|
||||
<TextField
|
||||
hintText="E.g. 0899976487"
|
||||
onChange={this.handleChangeHandphone}
|
||||
fullWidth={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Marital Status</p>
|
||||
<SelectField
|
||||
value={this.state.marital}
|
||||
onChange={this.handleChangeMarital}
|
||||
fullWidth={true}
|
||||
>
|
||||
{marital_status}
|
||||
</SelectField>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">ID Tax Number</p>
|
||||
<TextField
|
||||
hintText="E.g. 00000000000000000"
|
||||
onChange={this.handleChangeTaxNumber}
|
||||
fullWidth={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">ID Type</p>
|
||||
<SelectField
|
||||
value={this.state.id_type}
|
||||
onChange={this.handleChangeType}
|
||||
fullWidth={true}
|
||||
>
|
||||
{id_type}
|
||||
</SelectField>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">ID Number</p>
|
||||
<TextField
|
||||
hintText="E.g. 00000000000000"
|
||||
onChange={this.handleChangeNumber}
|
||||
fullWidth={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
185
src/common/pages/Customers/CustomerDialog/CustomerForm.js
Normal file
185
src/common/pages/Customers/CustomerDialog/CustomerForm.js
Normal file
@@ -0,0 +1,185 @@
|
||||
import React from 'react';
|
||||
import {inject, observer} from 'mobx-react';
|
||||
import {DatePicker, MenuItem, SelectField, TextField,} from 'material-ui';
|
||||
|
||||
// import '../../Service/style.scss';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class CustomerForm extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
gender : 1,
|
||||
name: '',
|
||||
email: '',
|
||||
date_of_birth: '',
|
||||
address: '',
|
||||
occupation: '',
|
||||
passport_number: '',
|
||||
...props.defaultValue
|
||||
};
|
||||
this.http = props.appstate.http;
|
||||
this.authStore = props.appstate.auth;
|
||||
}
|
||||
|
||||
handleAgents = (station) =>{
|
||||
this.setState({
|
||||
agent : station.value
|
||||
});
|
||||
};
|
||||
|
||||
handleGender = (station) =>{
|
||||
this.setState({
|
||||
gender : station.value
|
||||
});
|
||||
};
|
||||
|
||||
triggerOnChange() {
|
||||
if (this.props.onChangeData && typeof this.props.onChangeData === 'function') {
|
||||
this.props.onChangeData(this.state);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const gender = [
|
||||
<MenuItem key={0} value={0} primaryText="Choose Gender"/>,
|
||||
<MenuItem key={1} value={"M"} primaryText="Men"/>,
|
||||
<MenuItem key={2} value={"W"} primaryText="Women"/>,
|
||||
];
|
||||
|
||||
const wrapperText = key => ele => React.cloneElement(ele, {
|
||||
value: this.state[key],
|
||||
onChange: (e, v) => {
|
||||
this.setState({
|
||||
[key]: v
|
||||
}, () => this.triggerOnChange());
|
||||
}
|
||||
});
|
||||
|
||||
const wrapperSelect = key => ele => React.cloneElement(ele, {
|
||||
value: this.state[key],
|
||||
onChange: (e, k, v) => {
|
||||
this.setState({
|
||||
[key]: v
|
||||
}, () => this.triggerOnChange());
|
||||
}
|
||||
});
|
||||
|
||||
return(
|
||||
<div style={{
|
||||
paddingTop: 10
|
||||
}}>
|
||||
<div className="row">
|
||||
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Your Name</p>
|
||||
{wrapperText("name")(
|
||||
<TextField
|
||||
fullWidth={true}
|
||||
hintText="E.g. Michael Jordan"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Your Email</p>
|
||||
{wrapperText("email")(
|
||||
<TextField
|
||||
fullWidth={true}
|
||||
hintText="E.g. Michael.Jordan@domain.com"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div className="row">
|
||||
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Date of Birth</p>
|
||||
<DatePicker
|
||||
fullWidth={true}
|
||||
mode="landscape"
|
||||
hintText="2017-08-17"
|
||||
openToYearSelection={true}
|
||||
onChange={(e, v) => {
|
||||
this.setState({
|
||||
date_of_birth: v
|
||||
}, () => this.triggerOnChange());
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Gender</p>
|
||||
{wrapperSelect("gender")(
|
||||
<SelectField
|
||||
value={this.state.gender}
|
||||
onChange={this.handleGender}
|
||||
fullWidth={true}
|
||||
>
|
||||
{gender}
|
||||
</SelectField>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div className="row">
|
||||
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Passport Number</p>
|
||||
{wrapperText("passport_number")(
|
||||
<TextField
|
||||
hintText="E.g. X000000"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col s12 m6 l6">
|
||||
<div>
|
||||
<p className="label-form">Occupation</p>
|
||||
{wrapperText("occupation")(
|
||||
<TextField
|
||||
hintText="E.g. "
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col s12 m12 l12">
|
||||
<div>
|
||||
<p className="label-form">Address</p>
|
||||
{wrapperText("address")(
|
||||
<TextField
|
||||
hintText="E.g. Jl. Kemanggisan No.25 Jakarta Barat"
|
||||
multiLine={true}
|
||||
fullWidth={true}
|
||||
rows={1}
|
||||
rowsMax={4}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
import React from 'react';
|
||||
import {inject, observer} from 'mobx-react';
|
||||
import {DatePicker, MenuItem, SelectField, TextField,
|
||||
GridTile,
|
||||
GridList} from 'material-ui';
|
||||
|
||||
// import '../../Service/style.scss';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class IdentificationPassport extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.customer = props.appstate.customer;
|
||||
this.state = {
|
||||
|
||||
...props.defaultValue
|
||||
};
|
||||
this.http = props.appstate.http;
|
||||
this.authStore = props.appstate.auth;
|
||||
}
|
||||
|
||||
handleChangePassport = (event, index, value) =>{
|
||||
const file = event.nativeEvent.target.files[0];
|
||||
const allowedFile = ['jpg', 'jpeg', 'png', 'gif'];
|
||||
|
||||
const [ext] = file.name.split('.').reverse();
|
||||
|
||||
if (!allowedFile.includes(ext.toLowerCase())) {
|
||||
|
||||
}
|
||||
|
||||
this.http.upload(file).then((response) => {
|
||||
this.customer.CustomerData.passport_photo = "/api/v1"+response.path;
|
||||
});
|
||||
}
|
||||
|
||||
handleChangeIdentification = (event, index, value) =>{
|
||||
const file = event.nativeEvent.target.files[0];
|
||||
const allowedFile = ['jpg', 'jpeg', 'png', 'gif'];
|
||||
|
||||
const [ext] = file.name.split('.').reverse();
|
||||
|
||||
if (!allowedFile.includes(ext.toLowerCase())) {
|
||||
|
||||
}
|
||||
|
||||
this.http.upload(file).then((response) => {
|
||||
this.customer.CustomerData.id_photo = "/api/v1"+response.path;
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const styles = {
|
||||
root: {
|
||||
// display: 'flex',
|
||||
padding: '5px',
|
||||
flexWrap: 'wrap',
|
||||
justifyContent: 'space-around',
|
||||
},
|
||||
gridList: {
|
||||
display: 'flex',
|
||||
flexWrap: 'nowrap',
|
||||
overflowX: 'auto',
|
||||
},
|
||||
titleStyle: {
|
||||
color: 'rgb(0, 188, 212)',
|
||||
},
|
||||
radioButton: {
|
||||
marginTop: 16,
|
||||
},
|
||||
};
|
||||
|
||||
return(
|
||||
<div style={{
|
||||
|
||||
}}>
|
||||
<div className="row">
|
||||
<div className="col s12 m6 l6">
|
||||
<p className="label-form">Identification</p>
|
||||
<input
|
||||
type="file"
|
||||
onChange={this.handleChangeIdentification}
|
||||
accept="image/*"
|
||||
/>
|
||||
</div>
|
||||
<div className="col s12 m6 l6">
|
||||
<p className="label-form">Passport</p>
|
||||
<input
|
||||
type="file"
|
||||
onChange={this.handleChangePassport}
|
||||
accept="image/*"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col s12 m6 l6">
|
||||
<div className="row">
|
||||
<h4>
|
||||
Identification Photo View
|
||||
</h4>
|
||||
</div>
|
||||
<div className="row">
|
||||
<img src={this.http.appendImagePath(this.customer.CustomerData.id_photo)} width="100%" style={{marginBottom:'10px'}}/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col s12 m6 l6">
|
||||
<div className="row">
|
||||
<h4>
|
||||
Passport Photo View
|
||||
</h4>
|
||||
</div>
|
||||
<div className="row">
|
||||
<img src={this.http.appendImagePath(this.customer.CustomerData.passport_photo)} width="100%" style={{marginBottom:'10px'}}/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
244
src/common/pages/Customers/CustomerDialog/index.js
Normal file
244
src/common/pages/Customers/CustomerDialog/index.js
Normal file
@@ -0,0 +1,244 @@
|
||||
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 CustomerDetailForm from './CustomerDetailForm';
|
||||
import IdentificationPassport from './IdentificationPassport';
|
||||
import ArrowForwardIcon from 'material-ui/svg-icons/navigation/arrow-forward';
|
||||
import NavigationArrowBack from 'material-ui/svg-icons/navigation/arrow-back';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class CustomerDialogComponent extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
stepIndex: 0,
|
||||
formData: {},
|
||||
finished: false,
|
||||
openedDialog: false
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
this.customer = props.appstate.customer;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.setState({
|
||||
stepIndex: 0
|
||||
})
|
||||
this.customer.reset();
|
||||
}
|
||||
|
||||
onChangeForm(formData) {
|
||||
this.setState({formData});
|
||||
}
|
||||
|
||||
getStepContent(stepIndex) {
|
||||
switch (stepIndex) {
|
||||
case 0:
|
||||
return <CustomerDetailForm/>;
|
||||
|
||||
case 1:
|
||||
return <IdentificationPassport/>;
|
||||
}
|
||||
}
|
||||
|
||||
handleOpen = () => {
|
||||
this.setState({openedDialog: true})
|
||||
};
|
||||
|
||||
handleNext = () => {
|
||||
const {stepIndex} = this.state;
|
||||
if (stepIndex === 0) {
|
||||
if (this.customer.CustomerData.name === '' ||
|
||||
this.customer.CustomerData.date_of_birth === '' ||
|
||||
this.customer.CustomerData.email === '' ||
|
||||
this.customer.CustomerData.address === '' ||
|
||||
this.customer.CustomerData.occupation === '' ||
|
||||
this.customer.CustomerData.gender === '' ||
|
||||
this.customer.CustomerData.birth_place === '' ||
|
||||
this.customer.CustomerData.phone === '' ||
|
||||
this.customer.CustomerData.handphone === '' ||
|
||||
this.customer.CustomerData.martial_status === '' ||
|
||||
this.customer.CustomerData.id_tax_number === '' ||
|
||||
this.customer.CustomerData.id_type === '' ||
|
||||
this.customer.CustomerData.id_number === '' ||
|
||||
this.customer.CustomerData.passport_number === '' || this.customer.CustomerData.error_email != '') {
|
||||
this.handleOpen();
|
||||
} else {
|
||||
this.setState({
|
||||
stepIndex: stepIndex + 1,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handlePrev = () => {
|
||||
const {stepIndex} = this.state;
|
||||
if (stepIndex > 0) {
|
||||
this.setState({stepIndex: stepIndex - 1});
|
||||
}
|
||||
}
|
||||
|
||||
handleClose = () => {
|
||||
this.setState({openedDialog: false})
|
||||
};
|
||||
|
||||
save = () => {
|
||||
this.customer.create()
|
||||
.then(res => {
|
||||
this.globalUI.hideDialog(DIALOG.CUSTOMER.CREATE);
|
||||
this.customer.getAll();
|
||||
})
|
||||
}
|
||||
|
||||
handlePost = () => {
|
||||
this.agentStore.post().then(res => {
|
||||
this.props.history.push(LINKS.SETTING);
|
||||
this.globalUI.openSnackbar("Successfull Added Agent");
|
||||
});
|
||||
};
|
||||
|
||||
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 actions = [
|
||||
// <FlatButton
|
||||
// label="Cancel"
|
||||
// primary={true}
|
||||
// style={{marginRight: 10}}
|
||||
// onClick={() => this.globalUI.hideDialog(DIALOG.CUSTOMER.CREATE)}
|
||||
// />,
|
||||
// <RaisedButton
|
||||
// label="Submit"
|
||||
// primary={true}
|
||||
// onClick={() => this.save()}
|
||||
// />,
|
||||
// ];
|
||||
|
||||
|
||||
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"
|
||||
}}>Add New Customer</h4>
|
||||
{/*<IconButton*/}
|
||||
{/*iconClassName="material-icons"*/}
|
||||
{/*tooltip="Close"*/}
|
||||
{/*iconStyle={{*/}
|
||||
{/*color: 'grey',*/}
|
||||
{/*}}*/}
|
||||
{/*style={{*/}
|
||||
{/*position: 'absolute',*/}
|
||||
{/*right: 0,*/}
|
||||
{/*top: 0*/}
|
||||
{/*}}*/}
|
||||
{/*onClick={() => this.globalUI.hideDialog(DIALOG.CUSTOMER.CREATE)}*/}
|
||||
{/*>*/}
|
||||
{/*close*/}
|
||||
{/*</IconButton>*/}
|
||||
</div>
|
||||
;
|
||||
|
||||
return (
|
||||
<div>
|
||||
{/*<Dialog*/}
|
||||
{/*title="Add New Costumer"*/}
|
||||
{/*modal={false}*/}
|
||||
{/*autoScrollBodyContent={true}*/}
|
||||
{/*actions={actions}*/}
|
||||
{/*open={this.globalUI[DIALOG.CUSTOMER.CREATE]}*/}
|
||||
{/*onRequestClose={this.handleClose}>*/}
|
||||
{/*<CustomerForm onChangeData={this.onChangeForm.bind(this)} />*/}
|
||||
{/*</Dialog>*/}
|
||||
<Dialog
|
||||
title={<div>
|
||||
<div>{title}</div>
|
||||
<div style={{padding: "0px 14px 0px 0px", marginTop: 10}}>
|
||||
<Stepper activeStep={stepIndex}>
|
||||
<Step>
|
||||
<StepLabel style={{padding: "0px 14px 0px 0px", height: 52}}>Customer 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.globalUI.hideDialog(DIALOG.CUSTOMER.CREATE) : this.handlePrev()}
|
||||
/>
|
||||
{this.continueButton()}
|
||||
</div>}
|
||||
autoScrollBodyContent={true}
|
||||
repositionOnUpdate={true}
|
||||
open={this.globalUI[DIALOG.CUSTOMER.CREATE]}
|
||||
onRequestClose={this.handleClose}>
|
||||
<div style={{marginTop: 20}}>
|
||||
{this.getStepContent(stepIndex)}
|
||||
</div>
|
||||
</Dialog>
|
||||
<Dialog
|
||||
title="Warning"
|
||||
actions={actions}
|
||||
modal={false}
|
||||
autoScrollBodyContent={false}
|
||||
contentStyle={{width: 350}}
|
||||
open={this.state.openedDialog}
|
||||
onRequestClose={() => this.handleClose()}
|
||||
>
|
||||
Please Fill the form correctly
|
||||
</Dialog>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
283
src/common/pages/Customers/index.js
Normal file
283
src/common/pages/Customers/index.js
Normal file
@@ -0,0 +1,283 @@
|
||||
import React from 'react';
|
||||
import {inject, observer} from 'mobx-react';
|
||||
import {
|
||||
Card,
|
||||
Divider,
|
||||
MenuItem,
|
||||
RaisedButton,
|
||||
FlatButton,
|
||||
IconButton,
|
||||
Table,
|
||||
TableBody,
|
||||
TableHeader,
|
||||
TableHeaderColumn,
|
||||
TableRow,
|
||||
TableRowColumn,
|
||||
TextField,
|
||||
Toolbar,
|
||||
ToolbarGroup,
|
||||
Dialog,
|
||||
ToolbarSeparator
|
||||
} from 'material-ui';
|
||||
import SearchIcon from 'material-ui/svg-icons/action/search';
|
||||
import AddIcon from 'material-ui/svg-icons/content/add';
|
||||
import moment from "moment";
|
||||
import {Link} from 'react-router-dom';
|
||||
import {LINKS} from "../../routes";
|
||||
import CustomerDialog from './CustomerDialog';
|
||||
import {DIALOG} from "../../stores/global_ui";
|
||||
import EmptyComponent from "../EmptyComponent/index";
|
||||
import LoadingDialog from "../LoadingDialog";
|
||||
import Loader from 'react-loader-advanced';
|
||||
// import './style.scss';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class CustomerComponent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
open: false,
|
||||
value: 1,
|
||||
searchText: '',
|
||||
slideIndex: 0,
|
||||
customers: [
|
||||
{
|
||||
id: 'cus_461a1df1',
|
||||
name: 'Ridwan Abadi',
|
||||
email: 'welove6215@einrot.com',
|
||||
registered: moment(),
|
||||
agent: 'active'
|
||||
},
|
||||
{
|
||||
id: 'cus_461a1df2',
|
||||
name: 'Hasta Ragil',
|
||||
email: 'welove6215@einrot.com',
|
||||
registered: moment(),
|
||||
agent: 'blocked'
|
||||
},
|
||||
{
|
||||
id: 'cus_461a1df3',
|
||||
name: 'Tsabit',
|
||||
email: 'welove6215@einrot.com',
|
||||
registered: moment(),
|
||||
agent: 'pending'
|
||||
},
|
||||
{
|
||||
id: 'cus_461a1df4',
|
||||
name: 'Nugroho',
|
||||
email: 'welove6215@einrot.com',
|
||||
registered: moment(),
|
||||
agent: 'active'
|
||||
},
|
||||
]
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.http = props.appstate.http;
|
||||
this.authStore = props.appstate.auth;
|
||||
this.customer = props.appstate.customer;
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
console.log('Profile loaded!');
|
||||
// this.customer.getAll();
|
||||
this.globalUI.openLoading();
|
||||
this.customer.getAll().then(res => {
|
||||
this.globalUI.closeLoading();
|
||||
});
|
||||
}
|
||||
|
||||
handleOpen = () => {
|
||||
this.globalUI.showDialog(DIALOG.CUSTOMER.CREATE);
|
||||
};
|
||||
|
||||
handleClose = () => {
|
||||
this.setState({open: false});
|
||||
};
|
||||
|
||||
handleSubmit = () => {
|
||||
console.log("Customer Submitted");
|
||||
};
|
||||
|
||||
handleUpdateInput = (searchText) => {
|
||||
this.setState({
|
||||
searchText: searchText,
|
||||
});
|
||||
};
|
||||
|
||||
handleNewRequest = () => {
|
||||
this.setState({
|
||||
searchText: '',
|
||||
});
|
||||
};
|
||||
|
||||
tabsHandleChange = (value) => {
|
||||
this.setState({
|
||||
slideIndex: value,
|
||||
});
|
||||
};
|
||||
|
||||
handleChange = (event, index, value) => this.setState({value});
|
||||
|
||||
render() {
|
||||
const actions = [
|
||||
<FlatButton
|
||||
label="Cancel"
|
||||
onClick={this.handleClose}
|
||||
style={{marginRight: 12}}
|
||||
/>,
|
||||
<RaisedButton
|
||||
label='Save'
|
||||
primary={true}
|
||||
onClick={this.handleSubmit}
|
||||
/>
|
||||
];
|
||||
|
||||
const title =
|
||||
<div>
|
||||
<h4 style={{
|
||||
fontSize: 26,
|
||||
marginBottom: 0,
|
||||
marginTop: 0,
|
||||
fontWeight: 500,
|
||||
color: "white"
|
||||
}}>Register New Customer</h4>
|
||||
<p style={{fontSize: 13}}>
|
||||
Remember to put every detail of the customer, check their personal identification and make sure it's not fake.
|
||||
</p>
|
||||
<IconButton
|
||||
iconClassName="material-icons"
|
||||
tooltip="Close"
|
||||
iconStyle={{
|
||||
color: '#fff',
|
||||
}}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
top: 0
|
||||
}}
|
||||
onClick={this.handleClose}
|
||||
>
|
||||
close
|
||||
</IconButton>
|
||||
</div>
|
||||
;
|
||||
|
||||
const styles = {
|
||||
|
||||
radioButton: {
|
||||
marginBottom: 16,
|
||||
},
|
||||
};
|
||||
|
||||
const colors = [
|
||||
'Jakarta - Soekarno - Hatta (CGK)',
|
||||
'Bali',
|
||||
'Surabaya',
|
||||
'Yogyakarta',
|
||||
'Aceh',
|
||||
'Kalimantan',
|
||||
'Medan',
|
||||
'Papua',
|
||||
];
|
||||
|
||||
const items = [
|
||||
<MenuItem key={1} value={1} primaryText="All Maskapai"/>,
|
||||
<MenuItem key={2} value={2} primaryText="Air Asia"/>,
|
||||
<MenuItem key={3} value={3} primaryText="Weeknights"/>,
|
||||
<MenuItem key={4} value={4} primaryText="Weekends"/>,
|
||||
<MenuItem key={5} value={5} primaryText="Weekly"/>,
|
||||
];
|
||||
|
||||
const count = [
|
||||
<MenuItem key={1} value={1} primaryText="1"/>,
|
||||
<MenuItem key={2} value={2} primaryText="2"/>,
|
||||
<MenuItem key={3} value={3} primaryText="3"/>,
|
||||
<MenuItem key={4} value={4} primaryText="4"/>,
|
||||
<MenuItem key={5} value={5} primaryText="5"/>,
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="member containerMiddle animated fadeIn">
|
||||
<CustomerDialog/>
|
||||
<div style={{marginBottom: '16px'}}>
|
||||
<h3 className="headerMenu">Customers</h3>
|
||||
</div>
|
||||
<Card className="cardLite" style={{paddingBottom: 5}}>
|
||||
<Toolbar className="toolbarCard" style={{backgroundColor: '#fff'}}>
|
||||
<ToolbarGroup>
|
||||
<SearchIcon style={{marginRight: 8, color: "#999"}}/>
|
||||
<TextField
|
||||
hintText="Search customer"
|
||||
style={{fontSize: 14}}
|
||||
hintStyle={{fontSize: 14}}
|
||||
underlineShow={false}
|
||||
/>
|
||||
</ToolbarGroup>
|
||||
<ToolbarGroup className="ToolbarGroupLast">
|
||||
<ToolbarSeparator/>
|
||||
<RaisedButton onClick={this.handleOpen} className="ToolbarGroupLastButton" icon={<AddIcon/>}
|
||||
label="New Customer" primary={true}/>
|
||||
</ToolbarGroup>
|
||||
</Toolbar>
|
||||
<Divider/>
|
||||
<div>
|
||||
<Loader show={this.globalUI.loadingVisibility} message={<LoadingDialog />} messageStyle={{textAlign:'center'}} backgroundStyle={{backgroundColor: 'rgba(255,255,255,0.5)'}}>
|
||||
<Table selectable={false}>
|
||||
<TableHeader displaySelectAll={false}
|
||||
adjustForCheckbox={false}
|
||||
enableSelectAll={false}>
|
||||
<TableRow style={{height: 38, background: '#f6f9fc'}}>
|
||||
<TableHeaderColumn
|
||||
className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>ID</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Name</TableHeaderColumn>
|
||||
<TableHeaderColumn
|
||||
className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Email</TableHeaderColumn>
|
||||
<TableHeaderColumn
|
||||
className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Registered</TableHeaderColumn>
|
||||
<TableHeaderColumn
|
||||
className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto'}}>Agent</TableHeaderColumn>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody displayRowCheckbox={false}>
|
||||
{
|
||||
(this.customer.customers.length > 0) ?
|
||||
this.customer.customers.map(cust => {
|
||||
return (
|
||||
<TableRow key={cust.id}>
|
||||
<TableRowColumn>
|
||||
<Link
|
||||
to={`${LINKS.CUSTOMER}/${cust.id}`}
|
||||
key={cust.id}>{cust.name}</Link> -
|
||||
<code style={{color: '#424770'}}>{cust.id}</code>
|
||||
</TableRowColumn>
|
||||
<TableRowColumn>{cust.name}</TableRowColumn>
|
||||
<TableRowColumn>{cust.email}</TableRowColumn>
|
||||
<TableRowColumn>{moment(cust.registered).format("DD MMMM YYYY, HH:mm:ss")}</TableRowColumn>
|
||||
{(cust.agent == null)? <TableRowColumn>admin</TableRowColumn>
|
||||
:
|
||||
<TableRowColumn>
|
||||
<Link to={`${LINKS.MEMBER}/mem_84d0b93a`} key={'mem_84d0b93a'}>{(cust.agent == null)? 'admin' : cust.agent.name}</Link>
|
||||
- <code style={{color: '#424770'}}>{cust.agent_id}</code>
|
||||
</TableRowColumn>
|
||||
}
|
||||
</TableRow>
|
||||
)
|
||||
}) : <EmptyComponent type="empty" header="" content="There is no data in sight"/>
|
||||
}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</Loader>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
135
src/common/pages/Dashboard/CardAdmin.js
Normal file
135
src/common/pages/Dashboard/CardAdmin.js
Normal file
@@ -0,0 +1,135 @@
|
||||
import React from "react";
|
||||
import {inject, observer} from "mobx-react";
|
||||
import QueueAnim from 'rc-queue-anim';
|
||||
import "./style.scss";
|
||||
import {LINKS} from './../../routes'
|
||||
import {Link} from 'react-router-dom';
|
||||
import * as _ from 'lodash';
|
||||
import NumberFormat from 'react-number-format';
|
||||
import {
|
||||
Paper,
|
||||
Card,
|
||||
CardActions,
|
||||
CardHeader,
|
||||
CardMedia,
|
||||
CardTitle,
|
||||
CardText,
|
||||
FlatButton,
|
||||
GridList,
|
||||
GridTile,
|
||||
Divider,
|
||||
Step,
|
||||
Stepper,
|
||||
StepLabel,
|
||||
StepButton,
|
||||
RaisedButton,
|
||||
} from 'material-ui';
|
||||
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class CardAdmin extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
stepIndex: 1,
|
||||
stepAccount : false,
|
||||
stepDeposit : false,
|
||||
stepChallenge : false,
|
||||
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
this
|
||||
.globalUI
|
||||
.changeBackgroundColor("#f7f7f7");
|
||||
// .changeBackgroundColor("#208166");
|
||||
this.dashboardStore = props.appstate.dashboard;
|
||||
this.authStore = props.appstate.auth;
|
||||
this.userData = props.appstate.userData;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this
|
||||
.globalUI
|
||||
.changeBackgroundColor("#fff");
|
||||
}
|
||||
|
||||
getValue = (data)=> {
|
||||
if(data == null){
|
||||
return 0
|
||||
}
|
||||
else{
|
||||
return data
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
render() {
|
||||
|
||||
const contentStyle = {margin: '0 16px'};
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
||||
<div className="col s12 m4 l4 row">
|
||||
{/*<Card style={{backgroundColor: '#2196f3', minHeight: 145}} className="cardLite">*/}
|
||||
{/*<CardHeader*/}
|
||||
{/*style={{padding: '16px 16px 0',}}*/}
|
||||
{/*title={<h1 style={{fontSize: 22, fontWeight: '400', color: '#fff'}}>Total Deposit</h1>}*/}
|
||||
{/*/>*/}
|
||||
{/*<CardTitle style={{padding: '16px 16px 8px 16px'}}*/}
|
||||
{/*title={<h1 style={{fontSize: 38, fontWeight: "300", color: "#fff"}}><NumberFormat value={this.getValue(this.dashboardStore.dashboard.top.total[0].sum)} displayType={'text'} thousandSeparator={true} prefix={'IDR '} /><span*/}
|
||||
{/*className="saldo-analytic-percentage" style={{fontSize: 18}}><NumberFormat value={this.getValue(this.dashboardStore.dashboard.top.today[0].sum)} displayType={'text'} thousandSeparator={true} prefix={'IDR '} /></span></h1>}*/}
|
||||
{/*subtitle={<span style={{fontSize: 16, fontWeight: 300, color: '#fff'}}>Today</span>}/>*/}
|
||||
|
||||
{/*<CardText style={{padding: '8px 0 8px 0px', position: 'relative'}}>*/}
|
||||
{/*<Divider style={{marginBottom: 8, backgroundColor: '#3984c4'}}/>*/}
|
||||
{/*<span style={{fontSize: 16, fontWeight: 300, color: '#fff', paddingLeft: 16}}>Yesterday</span>*/}
|
||||
{/*<span style={{*/}
|
||||
{/*position: 'absolute',*/}
|
||||
{/*right: '16px',*/}
|
||||
{/*fontSize: 16,*/}
|
||||
{/*fontWeight: 400,*/}
|
||||
{/*paddingLeft: 16,*/}
|
||||
{/*color: "#fff"*/}
|
||||
{/*}}><NumberFormat value={this.getValue(this.dashboardStore.dashboard.top.yesterday[0].sum)} displayType={'text'} thousandSeparator={true} prefix={'IDR '} /></span>*/}
|
||||
{/*</CardText>*/}
|
||||
|
||||
{/*</Card>*/}
|
||||
|
||||
</div>
|
||||
<div className="col s12 m4 l4">
|
||||
<Card style={{minHeight: 145}} className="cardLite">
|
||||
<CardHeader
|
||||
style={{padding: '16px 16px 0',}}
|
||||
title={<h1 style={{fontSize: 22, fontWeight: '400'}}>Total Withdraw</h1>}
|
||||
/>
|
||||
|
||||
<CardTitle style={{padding: '16px 16px 8px 16px'}}
|
||||
title={<h1 style={{fontSize: 38, fontWeight: "300"}}><NumberFormat value={this.getValue(this.dashboardStore.dashboard.bottom.total[0].sum)} displayType={'text'} thousandSeparator={true} prefix={'IDR '} /><span
|
||||
className="saldo-analytic-percentage" style={{fontSize: 16}}><NumberFormat value={this.getValue(this.dashboardStore.dashboard.bottom.today[0].sum)} displayType={'text'} thousandSeparator={true} prefix={'IDR '} /></span></h1>}
|
||||
subtitle={<span style={{fontSize: 16, fontWeight: 300}}>Today</span>}/>
|
||||
|
||||
|
||||
<CardText style={{padding: '8px 0 8px 0px', position: 'relative'}}>
|
||||
<Divider style={{marginBottom: 8}}/>
|
||||
<span style={{fontSize: 16, fontWeight: 300, color: 'rgba(66, 71, 112, 0.54)', paddingLeft: 16}}>Yesterday</span>
|
||||
<span style={{position: 'absolute', right: '16px', fontSize: 16, fontWeight: 400, paddingLeft: 16}}><NumberFormat value={this.getValue(this.dashboardStore.dashboard.bottom.yesterday[0].sum)} displayType={'text'} thousandSeparator={true} prefix={'IDR '} /></span>
|
||||
</CardText>
|
||||
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
131
src/common/pages/Dashboard/CardAgent.js
Normal file
131
src/common/pages/Dashboard/CardAgent.js
Normal file
@@ -0,0 +1,131 @@
|
||||
import React from "react";
|
||||
import {inject, observer} from "mobx-react";
|
||||
import QueueAnim from 'rc-queue-anim';
|
||||
import "./style.scss";
|
||||
import {LINKS} from './../../routes'
|
||||
import {Link} from 'react-router-dom';
|
||||
import * as _ from 'lodash';
|
||||
import DC from 'decimal.js-light';
|
||||
import NumberFormat from 'react-number-format';
|
||||
import {
|
||||
Paper,
|
||||
Card,
|
||||
CardActions,
|
||||
CardHeader,
|
||||
CardMedia,
|
||||
CardTitle,
|
||||
CardText,
|
||||
FlatButton,
|
||||
GridList,
|
||||
GridTile,
|
||||
Divider,
|
||||
Step,
|
||||
Stepper,
|
||||
StepLabel,
|
||||
StepButton,
|
||||
RaisedButton,
|
||||
} from 'material-ui';
|
||||
|
||||
const {
|
||||
LineChart,
|
||||
AreaChart,
|
||||
BarChart,
|
||||
Bar,
|
||||
Line,
|
||||
XAxis,
|
||||
YAxis,
|
||||
ReferenceLine,
|
||||
CartesianGrid,
|
||||
Tooltip,
|
||||
Legend,
|
||||
Area,
|
||||
ResponsiveContainer
|
||||
} = require('recharts/umd/Recharts.min');
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class CardAgent extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
stepIndex: 1,
|
||||
stepAccount : false,
|
||||
stepDeposit : false,
|
||||
stepChallenge : false,
|
||||
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
this
|
||||
.globalUI
|
||||
.changeBackgroundColor("#f7f7f7");
|
||||
// .changeBackgroundColor("#208166");
|
||||
this.dashboardStore = props.appstate.dashboard;
|
||||
this.authStore = props.appstate.auth;
|
||||
this.userData = props.appstate.userData;
|
||||
this.transactionStore = props.appstate.transaction;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.transactionStore.getAmount();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this
|
||||
.globalUI
|
||||
.changeBackgroundColor("#fff");
|
||||
}
|
||||
|
||||
getValue = (data)=> {
|
||||
if(data == null){
|
||||
return 0
|
||||
}
|
||||
else{
|
||||
return data
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
render() {
|
||||
const money = new DC(this.transactionStore.saldo.amount || 0).toFixed(2);
|
||||
const uang = <NumberFormat value={money} displayType={'text'} thousandSeparator={true} prefix={'IDR '} />;
|
||||
const contentStyle = {margin: '0 16px'};
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
||||
<div className="col s12 m4 l4 row">
|
||||
<Card style={{backgroundColor: '#2196f3', minHeight: 245}} className="cardLite">
|
||||
<CardHeader
|
||||
style={{padding: '16px 16px 0',}}
|
||||
title={<h1 style={{fontSize: 22, fontWeight: '400', color: '#fff'}}>Wallet</h1>}
|
||||
/>
|
||||
<CardTitle style={{padding: '16px 16px 8px 16px'}}
|
||||
title={<h1 style={{fontSize: 38, fontWeight: "300", color: "#fff"}}>{uang}<span
|
||||
className="saldo-analytic-percentage" style={{fontSize: 18}}>{/*HERE*/}</span></h1>}
|
||||
subtitle={<span style={{fontSize: 16, fontWeight: 300, color: '#fff'}}><span style={{fontSize:24,fontWeight:'300'}}></span></span>}/>
|
||||
|
||||
<CardText style={{padding: "120px 0px 20px 0px", position: 'relative'}}>
|
||||
<Divider style={{marginBottom: 8, backgroundColor: '#3984c4'}}/>
|
||||
<span style={{fontSize: 16, fontWeight: 300, color: '#fff', paddingLeft: 16}}>Your Balance</span>
|
||||
<span style={{
|
||||
position: 'absolute',
|
||||
right: '16px',
|
||||
fontSize: 16,
|
||||
fontWeight: 400,
|
||||
paddingLeft: 16,
|
||||
color: "#fff"
|
||||
}}>{/**/}</span>
|
||||
</CardText>
|
||||
|
||||
</Card>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
54
src/common/pages/Dashboard/SimpleAreaChart.js
Normal file
54
src/common/pages/Dashboard/SimpleAreaChart.js
Normal file
@@ -0,0 +1,54 @@
|
||||
import * as React from 'react';
|
||||
import {inject, observer} from "mobx-react";
|
||||
|
||||
const {
|
||||
LineChart,
|
||||
AreaChart,
|
||||
BarChart,
|
||||
Bar,
|
||||
Line,
|
||||
XAxis,
|
||||
YAxis,
|
||||
ReferenceLine,
|
||||
CartesianGrid,
|
||||
Tooltip,
|
||||
Legend,
|
||||
Area,
|
||||
ResponsiveContainer
|
||||
} = require('recharts/umd/Recharts.min');
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class SimpleAreaChart extends React.Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
this.dashboardStore = props.appstate.dashboard;
|
||||
this.userData = props.appstate.userData;
|
||||
}
|
||||
render() {
|
||||
const data = [
|
||||
{name: 'Jan', uv: 4000, pv: 2400, amt: 2400},
|
||||
{name: 'Feb', uv: 3000, pv: 1398, amt: 2210},
|
||||
{name: 'Mar', uv: 2000, pv: 9800, amt: 2290},
|
||||
{name: 'Apr', uv: 2780, pv: 3908, amt: 2000},
|
||||
{name: 'May', uv: 1890, pv: 4800, amt: 2181},
|
||||
{name: 'Jun', uv: 2390, pv: 3800, amt: 2500},
|
||||
{name: 'Jul', uv: 3490, pv: 4300, amt: 2100},
|
||||
];
|
||||
return (
|
||||
<ResponsiveContainer>
|
||||
<LineChart width={600} height={(this.userData.role === 'admin') ? 305 : 220} data={data}
|
||||
margin={{top: 5, right: 30, left: 5, bottom: 5}}>
|
||||
<XAxis dataKey="name" fontSize={10}/>
|
||||
<YAxis fontSize={10} />
|
||||
<CartesianGrid strokeDasharray="0.1 0.1"/>
|
||||
<Tooltip/>
|
||||
<Legend />
|
||||
<Line type="natural" dataKey="pv" stroke="#8884d8" activeDot={{r: 8}}/>
|
||||
<Line type="monotone" dataKey="uv" stroke="#82ca9d" />
|
||||
</LineChart>
|
||||
</ResponsiveContainer>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
506
src/common/pages/Dashboard/index.js
Normal file
506
src/common/pages/Dashboard/index.js
Normal file
@@ -0,0 +1,506 @@
|
||||
import React from "react";
|
||||
import {inject, observer} from "mobx-react";
|
||||
import QueueAnim from 'rc-queue-anim';
|
||||
import "./style.scss";
|
||||
import NumberFormat from 'react-number-format';
|
||||
import {LINKS} from './../../routes'
|
||||
import {Link} from 'react-router-dom';
|
||||
import CardAdmin from './CardAdmin';
|
||||
import CardAgent from './CardAgent';
|
||||
import moment from 'moment';
|
||||
import {Icon, Button, notification, Table, Tooltip as TooltipAntd} from 'antd';
|
||||
import DC from 'decimal.js-light';
|
||||
import {
|
||||
Paper,
|
||||
Card,
|
||||
CardActions,
|
||||
CardHeader,
|
||||
CardMedia,
|
||||
CardTitle,
|
||||
CardText,
|
||||
FlatButton,
|
||||
GridList,
|
||||
GridTile,
|
||||
Divider, ListItem, List
|
||||
} from 'material-ui';
|
||||
import EmptyComponent from '../EmptyComponent';
|
||||
import * as _ from 'lodash';
|
||||
import {grey400, darkBlack, lightBlack, black} from 'material-ui/styles/colors';
|
||||
import './style.scss';
|
||||
import {Carousel} from 'react-responsive-carousel'
|
||||
import {ActionGrade, ContentDrafts, ContentInbox, ContentSend} from "material-ui/svg-icons/index";
|
||||
import {constant} from "../../config/const";
|
||||
|
||||
const {
|
||||
LineChart,
|
||||
AreaChart,
|
||||
BarChart,
|
||||
Bar,
|
||||
Line,
|
||||
XAxis,
|
||||
YAxis,
|
||||
ReferenceLine,
|
||||
CartesianGrid,
|
||||
Tooltip,
|
||||
Legend,
|
||||
Area,
|
||||
ResponsiveContainer
|
||||
} = require('recharts/umd/Recharts.min');
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class DashboardComponent extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
list: [],
|
||||
my_item: 0,
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
this
|
||||
.globalUI
|
||||
.changeBackgroundColor("#f7f7f7");
|
||||
// .changeBackgroundColor("#208166");
|
||||
this.dashboardStore = props.appstate.dashboard;
|
||||
this.http = props.appstate.http;
|
||||
this.packageStore = props.appstate.packages;
|
||||
this.user = props.appstate.user;
|
||||
this.userData = props.appstate.userData;
|
||||
this.transactionStore = props.appstate.transaction;
|
||||
this.taskStore = props.appstate.task;
|
||||
this.myStoreItem = props.appstate.myStoreItem;
|
||||
this.orderStore = props.appstate.order;
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.transactionStore.getAmount();
|
||||
this.dashboardStore.getData();
|
||||
this.packageStore.getAllPackages();
|
||||
if (this.userData.role === 'admin') {
|
||||
this.taskStore.getAllDeposit();
|
||||
} else {
|
||||
this.transactionStore.getAll();
|
||||
this.checkStatus();
|
||||
}
|
||||
this.myStoreItem.getAll().then(res => {
|
||||
this.setState({
|
||||
my_item: res.max
|
||||
});
|
||||
});
|
||||
this.globalUI.openLoading();
|
||||
this.orderStore.getAllOrder().then(res => {
|
||||
this.globalUI.closeLoading();
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this
|
||||
.globalUI
|
||||
.changeBackgroundColor("#fff");
|
||||
}
|
||||
|
||||
checkStatus = () => {
|
||||
this.transactionStore.list.map((item, index) => {
|
||||
if (item.status !== 'created') {
|
||||
this.state.list.push(item);
|
||||
} else {
|
||||
// return this.state.list;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
iniUntukstatus = (text) => {
|
||||
if(text == '') {
|
||||
<div><span className='status-pill smaller process'/><span>No Status</span></div>
|
||||
}
|
||||
else if(text == 'Finished'){
|
||||
return (<div><span className='status-pill smaller process'/><span>Finished</span></div>)
|
||||
}
|
||||
else if(text == 'Pending Payment'){
|
||||
return (<div><span className='status-pill smaller pending'/><span>Pending Payment</span></div>)
|
||||
}
|
||||
else{
|
||||
return (<div><span className='status-pill smaller'/><span>No Status</span></div>)
|
||||
}
|
||||
};
|
||||
|
||||
filterOrder =(it)=>{
|
||||
if(this.orderStore.filterBy === 'active'){
|
||||
return it.order_status_id === constant.ORDER_STATUSES.PREORDER_WAITING_STORE_RESPONSE || it.order_status_id === constant.ORDER_STATUSES.PROCESSING || it.order_status_id == constant.ORDER_STATUSES.ON_SHIPPING_RETRY;
|
||||
}
|
||||
else{
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const undeposit_fund = <NumberFormat value={new DC(this.transactionStore.wallet.pending_payment_to_wallet || 0).toFixed(2)} displayType={'text'} thousandSeparator={true} prefix={'Rp '}/>;
|
||||
const balance = <NumberFormat value={new DC(this.transactionStore.wallet.balance || 0).toFixed(2)} displayType={'text'} thousandSeparator={true} prefix={'Rp '}/>;
|
||||
const dataSource = [
|
||||
// this.orderStore.orderList.map((item, index) => (
|
||||
// {
|
||||
// key: item.order_id,
|
||||
// noOrder: item.order_id,
|
||||
// customer: item.user_orders.user.email,
|
||||
// date: item.order_id,
|
||||
// hours: '12:00',
|
||||
// items: item.order_id,
|
||||
// status: item.order_id,
|
||||
// total: item.order_id,
|
||||
// }
|
||||
// ))
|
||||
{
|
||||
key: '1',
|
||||
noOrder: '180801061774YSV',
|
||||
customer: 'Mike',
|
||||
date: 'Yesterday',
|
||||
hours: '13:00',
|
||||
items: 'Hannah dress',
|
||||
status: 'Processing',
|
||||
total: 'Rp200.000',
|
||||
}
|
||||
, {
|
||||
key: '2',
|
||||
noOrder: '180801061774YSV',
|
||||
customer: 'Mike',
|
||||
date: 'Yesterday',
|
||||
hours: '13:00',
|
||||
items: 'Hannah dress',
|
||||
status: 'Processing',
|
||||
total: 'Rp200.000',
|
||||
}, {
|
||||
key: '3',
|
||||
noOrder: '190801061774YSV',
|
||||
customer: 'Mike',
|
||||
date: 'Feb 16, 2018',
|
||||
hours: '10:00',
|
||||
items: '10 Downing',
|
||||
status: 'Processing',
|
||||
total: 'Rp200.000',
|
||||
}, {
|
||||
key: '4',
|
||||
noOrder: '200801061774YSV',
|
||||
customer: 'Mike',
|
||||
date: 'Feb 15, 2018',
|
||||
hours: '20:00',
|
||||
items: '10 Downing Street',
|
||||
status: 'Processing',
|
||||
total: 'Rp200.000',
|
||||
}
|
||||
]
|
||||
|
||||
const columns = [{
|
||||
title: 'Id',
|
||||
dataIndex: 'this.orderStore.orderList.id',
|
||||
key: 'this.orderStore.orderList.id',
|
||||
className: 'recentOrder-noOrder',
|
||||
render: (text, data) => <Link to={`${LINKS.ORDER}/${data.id}`}
|
||||
key={data.order_id}>{(data.id.split("-")[0])}</Link>,
|
||||
|
||||
},{
|
||||
title: 'Customer',
|
||||
dataIndex: 'user_orders.user.email',
|
||||
key: 'user_orders.user.email',
|
||||
className: 'recentOrder-noOrder',
|
||||
render: (text, data) => <span>{text}</span>
|
||||
}, {
|
||||
title: 'Date',
|
||||
key: 'created_at',
|
||||
className: 'recentOrder-date',
|
||||
render: (text) => (
|
||||
<div>
|
||||
<span>{moment(text.created_at).format('MMM DD, YYYY')}</span> <span className='smaller lighter'>{moment(text.created_at).format('hh:mm')}</span>
|
||||
</div>
|
||||
)
|
||||
}, {
|
||||
title: 'Status',
|
||||
dataIndex: 'this.orderStore.orderList.order_status.name',
|
||||
key: 'this.orderStore.orderList.order_status.name',
|
||||
className: 'recentOrder-status',
|
||||
render: (text, data) =>
|
||||
(data.order_status == null) ? "No Status" : <div><span
|
||||
className={((data.order_status.name) === 'Preorder Buyer Decline') ? 'status-pill smaller red' : (data.order_status.name === 'Processing') ? 'status-pill smaller process' : ' status-pill smaller pending'}/><span>{(data.order_status.name).split('Preorder')}</span>
|
||||
</div>
|
||||
|
||||
|
||||
}, {
|
||||
title: 'Total',
|
||||
dataIndex: 'user_orders.total',
|
||||
key: 'user_orders.total',
|
||||
className: 'recentOrder-customer',
|
||||
render: (text, data, value) => {
|
||||
return <NumberFormat style={{color: ((data.order_status.name) === 'Preorder Buyer Decline') ? 'red' : '#000'}} value={data.user_orders.total} displayType={'text'} thousandSeparator={true} prefix={'Rp. '} />
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="dashboard animated fadeIn">
|
||||
<div className="row ">
|
||||
<div className="col s12 m9 l9 col-leftDashboard" style={{marginBottom: 0}}>
|
||||
<div className="row element-wrapper no-margin">
|
||||
<div className='element-header'>
|
||||
<h3>Sales Dashboard</h3>
|
||||
</div>
|
||||
<div className="col s12 m4 l4" style={{marginBottom: 0}}>
|
||||
<Card className="cardLite cardDashboard">
|
||||
<h3 style={{
|
||||
display: 'block',
|
||||
fontSize: '.63rem',
|
||||
textTransform: 'uppercase',
|
||||
color: '#0006',
|
||||
letterSpacing: 1
|
||||
}}> Items Sold</h3>
|
||||
<div className="value">{this.dashboardStore.data.item_sold}</div>
|
||||
<div>
|
||||
<Link to={LINKS.ITEMS} className="btnFlatUnderline ">
|
||||
<span>View Detail</span>
|
||||
<Icon className="ml-8" type="right"/>
|
||||
</Link>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div className="col s12 m4 l4" style={{marginBottom: 0}}>
|
||||
<Card className="cardLite cardDashboard">
|
||||
<h3 style={{
|
||||
display: 'block',
|
||||
fontSize: '.63rem',
|
||||
textTransform: 'uppercase',
|
||||
color: '#0006',
|
||||
letterSpacing: 1
|
||||
}}> Items</h3>
|
||||
<div className="value">{this.dashboardStore.data.item}</div>
|
||||
<div>
|
||||
<Link to={LINKS.ITEMS} className="btnFlatUnderline ">
|
||||
<span>View Items</span>
|
||||
<Icon className="ml-8" type="right"/>
|
||||
</Link>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div className="col s12 m4 l4" style={{marginBottom: 0}}>
|
||||
<Card className="cardLite cardDashboard">
|
||||
<h3 style={{
|
||||
display: 'block',
|
||||
fontSize: '.63rem',
|
||||
textTransform: 'uppercase',
|
||||
color: '#0006',
|
||||
letterSpacing: 1
|
||||
}}> Process Order</h3>
|
||||
<div className="value oldGreeen">{this.dashboardStore.data.order}</div>
|
||||
<div>
|
||||
<Link to={LINKS.ORDER} className="btnFlatUnderline green">
|
||||
<span>View Order</span>
|
||||
<Icon className="ml-8" type="right"/>
|
||||
</Link>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row element-wrapper">
|
||||
|
||||
<div className='element-header'>
|
||||
<h3>Recent Order</h3>
|
||||
</div>
|
||||
<div className="col s12 m12 l12" style={{marginBottom: 0}}>
|
||||
<Table
|
||||
pagination={false}
|
||||
className='table-padded'
|
||||
dataSource={this.orderStore.orderList.filter(this.filterOrder).slice(0, 5)}
|
||||
columns={columns}
|
||||
onRow={(record) => {
|
||||
return {
|
||||
onClick: () => {
|
||||
this.props.history.push(`${LINKS.ORDER}/${record.id}`);
|
||||
}, // click row
|
||||
};
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/*<Card className="cardLite" style={{marginBottom: (window.innerWidth < 600) ? 10 : 10, height: "auto"}}>*/}
|
||||
{/*<CardHeader*/}
|
||||
{/*title={<h1 style={{fontSize: 22, fontWeight: '400'}}>Revenue by services</h1>}/>*/}
|
||||
{/*<div style={{height: (this.userData.role === 'admin') ? "355px" : "237px", maxWidth: '100%'}}>*/}
|
||||
{/*<SimpleAreaChart/>*/}
|
||||
{/*</div>*/}
|
||||
{/*</Card>*/}
|
||||
</div>
|
||||
|
||||
|
||||
<div className="col s12 m3 l3 col-rightDashboard">
|
||||
<section className='row element-wrapper'>
|
||||
<div className='element-header'>
|
||||
<h3>Quick Links</h3>
|
||||
</div>
|
||||
<div className="col s12 m12 l12">
|
||||
<Button icon={"plus-circle-o"} className={'fullWidthButton btnSmCustom btnSmCustomWhite'}
|
||||
style={{marginBottom: '0.5rem'}} onClick={() => this.props.history.push(`${LINKS.FORM_UPLOAD}`)}>Create New Item</Button>
|
||||
<Button icon={"exception"} className={'fullWidthButton btnSmCustom btnSmCustomWhite'}
|
||||
style={{marginBottom: '0.5rem'}} onClick={() => this.props.history.push(`${LINKS.INBOX}`)}>Chat Inbox</Button>
|
||||
{this.props.appstate.userData.role === 'store' && <Button icon={"home"} className={'fullWidthButton btnSmCustom btnSmCustomWhite'}
|
||||
style={{marginBottom: '0.5rem'}} onClick={() => this.props.history.push(`${LINKS.STORES}`)}>Store Setting</Button>}
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<div className='element-header'>
|
||||
<h3>Financial Overview</h3>
|
||||
</div>
|
||||
<div className="col s12 m12 l12">
|
||||
<Card className="cardLite cardDashboard">
|
||||
<h3 style={{
|
||||
display: 'block',
|
||||
fontSize: '.63rem',
|
||||
textTransform: 'uppercase',
|
||||
color: '#0006',
|
||||
letterSpacing: 1
|
||||
}}> Undeposited Funds <TooltipAntd title="Your store pending payment"><Icon
|
||||
style={{color: '#6772e5', fontSize: '.7rem'}} type="info-circle"/></TooltipAntd></h3>
|
||||
<div>
|
||||
<a className=" btnFlatUnderlineSingleBlack" style={{color:'#3E4B5B'}}>
|
||||
<span>{undeposit_fund}</span>
|
||||
{/*<Icon className="ml-8" type="right"/>*/}
|
||||
</a>
|
||||
</div>
|
||||
<Divider className='divider-financial'/>
|
||||
<h3 style={{
|
||||
display: 'block',
|
||||
fontSize: '.63rem',
|
||||
textTransform: 'uppercase',
|
||||
color: '#0006',
|
||||
letterSpacing: 1
|
||||
}}> Total Balance <TooltipAntd title="Your store total balance"><Icon
|
||||
style={{color: '#6772e5', fontSize: '.7rem'}} type="info-circle"/></TooltipAntd></h3>
|
||||
<div>
|
||||
<a className=" btnFlatUnderlineSingle">
|
||||
<span>{balance}</span>
|
||||
{/*<Icon className="ml-8" type="right"/>*/}
|
||||
</a>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{/*{(this.userData.role === 'admin') ? <CardAdmin/> : <CardAgent/>}*/}
|
||||
</div>
|
||||
|
||||
|
||||
{/*<div className="row">*/}
|
||||
{/*<div className="col s12 m8 l8">*/}
|
||||
{/*<Card className="cardLite" style={{maxHeight: 400}}>*/}
|
||||
{/*{(!this.packageStore.isPackageEmpty) ?*/}
|
||||
{/*<Carousel showThumbs={true}*/}
|
||||
{/*autoPlay={true}*/}
|
||||
{/*dynamicHeight={true}*/}
|
||||
{/*infiniteLoop={true}*/}
|
||||
{/*showStatus={false}*/}
|
||||
{/*stopOnHover={true}*/}
|
||||
{/*showIndicators={false}>*/}
|
||||
{/*{this.packageStore.packagesList.map((tile, index) => (*/}
|
||||
{/*<Link key={index} to={{pathname: `${LINKS.SERVICE_PACKAGES}/${tile.id}`, query: {data: tile}}}>*/}
|
||||
{/*<CardMedia>*/}
|
||||
{/*<img src={this.http.appendImagePath(tile.banner)} style={{objectFit: "cover", height: 330}}/>*/}
|
||||
{/*<div className="legend">*/}
|
||||
{/*<h1>{tile.name} </h1>*/}
|
||||
{/*<p><NumberFormat value={tile.price} displayType={'text'} thousandSeparator={true}*/}
|
||||
{/*prefix={'IDR '}/></p>*/}
|
||||
{/*</div>*/}
|
||||
{/*</CardMedia>*/}
|
||||
{/*</Link>*/}
|
||||
{/*))}*/}
|
||||
{/*</Carousel>*/}
|
||||
{/*: <div></div>*/}
|
||||
{/*}*/}
|
||||
{/*</Card>*/}
|
||||
{/*</div>*/}
|
||||
{/*<div className="col s12 m4 l4">*/}
|
||||
{/*<Card className="cardLite" style={{marginBottom: (window.innerWidth < 600) ? 10 : 10, height: "auto"}}>*/}
|
||||
{/*<CardHeader*/}
|
||||
{/*title={<h1 style={{fontSize: 22, fontWeight: '400'}}>Latest News</h1>}/>*/}
|
||||
{/*<List>*/}
|
||||
{/*<Divider/>*/}
|
||||
{/*{*/}
|
||||
{/*(this.userData.role === 'admin') ?*/}
|
||||
{/*(!this.taskStore.isEmpty) ?*/}
|
||||
{/*this.taskStore.tasks.slice(0, 5).map((item, index) => {*/}
|
||||
{/*return (item.type == 'deposit' || item.type == 'withdraw') ? (*/}
|
||||
{/*<Link to={`${LINKS.TASKS}/${item.transaction_id}`}>*/}
|
||||
{/*<ListItem*/}
|
||||
{/*// leftAvatar={<Avatar src="images/ok-128.jpg" />}*/}
|
||||
{/*primaryText={_.capitalize(item.type) + " Request"}*/}
|
||||
{/*secondaryText={*/}
|
||||
{/*<div>*/}
|
||||
{/*<p>*/}
|
||||
{/*<span style={{color: darkBlack}}>{item.user.username}</span> --*/}
|
||||
{/*<NumberFormat value={item.amount} displayType={'text'} thousandSeparator={true}*/}
|
||||
{/*prefix={'IDR '}/>*/}
|
||||
{/*</p>*/}
|
||||
{/*<p style={{fontSize: 10, color: black}}>{moment(item.created_at).fromNow()}</p>*/}
|
||||
{/*</div>*/}
|
||||
{/*}*/}
|
||||
{/*secondaryTextLines={2}*/}
|
||||
{/*/>*/}
|
||||
{/*</Link>*/}
|
||||
{/*) :*/}
|
||||
{/*(*/}
|
||||
{/*<Link to={`${LINKS.SERVICE_AIRLINES_REVIEW}/${item.id}`}>*/}
|
||||
{/*<ListItem*/}
|
||||
{/*// leftAvatar={<Avatar src="images/ok-128.jpg" />}*/}
|
||||
{/*primaryText={_.capitalize(item.type) + " Request"}*/}
|
||||
{/*secondaryText={*/}
|
||||
{/*<div>*/}
|
||||
{/*<p>*/}
|
||||
{/*<span style={{color: darkBlack}}>{item.customer.name}</span>*/}
|
||||
{/*-- {item.request_data.selectedDepartureFlight.fromcity}*/}
|
||||
{/*TO {item.request_data.selectedDepartureFlight.tocity}*/}
|
||||
{/*</p>*/}
|
||||
{/*<p style={{fontSize: 10, color: black}}>{moment(item.created_at).fromNow()}</p>*/}
|
||||
{/*</div>*/}
|
||||
{/*}*/}
|
||||
{/*secondaryTextLines={2}*/}
|
||||
{/*/>*/}
|
||||
{/*</Link>*/}
|
||||
{/*);*/}
|
||||
{/*}) : <EmptyComponent width="" image="default4" type="empty" header="" content="No News yet."/>*/}
|
||||
{/*:*/}
|
||||
{/*(this.state.list.length > 0) ?*/}
|
||||
{/*this.state.list.slice(0, 5).map((item, index) => {*/}
|
||||
{/*return (*/}
|
||||
{/*<ListItem*/}
|
||||
{/*primaryText={`Your ${_.capitalize(item.type.name)} Request Has Been ${_.capitalize(item.status)}`}*/}
|
||||
{/*secondaryText={*/}
|
||||
{/*<Link*/}
|
||||
{/*to={`${LINKS.WALLET}/${item.id}`}*/}
|
||||
{/*>*/}
|
||||
{/*<p>*/}
|
||||
{/*<span style={{color: darkBlack}}>{_.capitalize(item.type.name)}</span> --*/}
|
||||
{/*<NumberFormat value={item.amount} displayType={'text'} thousandSeparator={true}*/}
|
||||
{/*prefix={'IDR '}/>*/}
|
||||
{/*</p>*/}
|
||||
{/*<p style={{fontSize: 10, color: black}}>{moment(item.updated_at).fromNow()}</p>*/}
|
||||
{/*</Link>*/}
|
||||
{/*}*/}
|
||||
{/*/>*/}
|
||||
{/*);*/}
|
||||
{/*}) : <EmptyComponent width="" image="default4" type="empty" header="" content="No News yet."/>*/}
|
||||
{/*}*/}
|
||||
{/*</List>*/}
|
||||
{/*<Divider/>*/}
|
||||
{/*</Card>*/}
|
||||
{/*</div>*/}
|
||||
{/*</div>*/}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
213
src/common/pages/Dashboard/style.scss
Normal file
213
src/common/pages/Dashboard/style.scss
Normal file
@@ -0,0 +1,213 @@
|
||||
.dashboard {
|
||||
margin-top: 35px;
|
||||
.container {
|
||||
padding: 25px;
|
||||
.ant-card {
|
||||
background: #fff;
|
||||
border-radius: 0;
|
||||
font-size: 12px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition: all .3s;
|
||||
}
|
||||
.ant-card-head {
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
background: #fff;
|
||||
border-bottom: 0 solid #e9e9e9;
|
||||
padding: 0 24px;
|
||||
}
|
||||
.ant-card:hover {
|
||||
box-shadow: 4px 4px 40px rgba(0, 0, 0, .05);
|
||||
border-color: transparent;
|
||||
}
|
||||
.ant-card-body-dashboard {
|
||||
padding: 10px;
|
||||
}
|
||||
.ant-table-pagination {
|
||||
margin-right: 20px;
|
||||
}
|
||||
.paddingLeft20 {
|
||||
padding-left: 25px;
|
||||
}
|
||||
.overlay-performance {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 360px;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
z-index: 99;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.overlay-task {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 247px;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
z-index: 99;
|
||||
left: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.overlay-performance h3 {
|
||||
font-size: 20px;
|
||||
color: #565656;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.overlay-task h3 {
|
||||
font-size: 18px;
|
||||
color: #565656;;
|
||||
font-weight: 300;
|
||||
}
|
||||
span.saldo-analytic-percentage {
|
||||
position: absolute !important;
|
||||
right: 16px !important;
|
||||
display: block;
|
||||
}
|
||||
|
||||
}
|
||||
.cardDashboard {
|
||||
padding: 1.5rem 2rem;
|
||||
margin-bottom: 1rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.cardDashboard:hover {
|
||||
-webkit-transform: translateY(-5px) scale(1.02);
|
||||
transform: translateY(-5px) scale(1.02);
|
||||
-webkit-box-shadow: 0 5px 12px rgba(126,142,177,0.2);
|
||||
box-shadow: 0 5px 12px rgba(126,142,177,0.2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
.value {
|
||||
font-size: 1.8rem;
|
||||
letter-spacing: 1px;
|
||||
line-height: 1.2;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.element-header {
|
||||
border-bottom: 1px solid rgba(0, 0, 0, .05);
|
||||
padding-bottom: 1rem;
|
||||
margin-bottom: 2rem;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.btnSmCustom {
|
||||
padding: .25rem .5rem;
|
||||
font-size: .775rem;
|
||||
border-radius: 4px;
|
||||
color: #292b2c;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.btnFlatUnderline, .btnFlatUnderlineSingleBlack, .btnFlatUnderlineSingle {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.btnFlatUnderline span {
|
||||
border-bottom: 2px solid #6772e5;
|
||||
}
|
||||
|
||||
.btnFlatUnderlineSingleBlack {
|
||||
border-bottom: 1px solid #3E4B5B;
|
||||
padding-bottom: 0.15em;
|
||||
}
|
||||
|
||||
.btnFlatUnderlineSingle {
|
||||
border-bottom: 1px solid #6772e5;
|
||||
padding-bottom: 0.15em;
|
||||
}
|
||||
|
||||
.gold span {
|
||||
border-bottom: 2px solid #BE8B1C;
|
||||
}
|
||||
|
||||
.green span {
|
||||
border-bottom: 2px solid #008000;
|
||||
}
|
||||
|
||||
.green:hover {
|
||||
color: #5d961f;
|
||||
}
|
||||
|
||||
.green:hover span {
|
||||
border-bottom: 2px solid #5d961f;
|
||||
}
|
||||
|
||||
.btnFlatUnderline i {
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.btnFlatUnderline:hover i {
|
||||
transform: translateX(5px);
|
||||
|
||||
}
|
||||
|
||||
.btnSmCustomWhite {
|
||||
color: #292b2c;
|
||||
background-color: #fff;
|
||||
border: 2px solid #fff;
|
||||
}
|
||||
|
||||
.btnSmCustomWhite:hover {
|
||||
color: #292b2c;
|
||||
background-color: #ececec;
|
||||
border: 2px solid #e6e5e5;
|
||||
}
|
||||
|
||||
.element-wrapper {
|
||||
padding-bottom: 3rem;
|
||||
}
|
||||
|
||||
.element-wrapper-row {
|
||||
padding-bottom: 2.1rem;
|
||||
|
||||
}
|
||||
|
||||
.status-pill {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 30px;
|
||||
background-color: #eee;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.table-padded .smaller {
|
||||
font-size: .72rem;
|
||||
}
|
||||
|
||||
.table-padded .lighter {
|
||||
color: rgba(90, 99, 126, .49);
|
||||
}
|
||||
|
||||
.status-pill.smaller {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
.status-pill.pending {
|
||||
background-color: #f8bc34;
|
||||
}
|
||||
|
||||
.status-pill.process {
|
||||
background-color: #71c21a;
|
||||
}
|
||||
|
||||
.divider-financial {
|
||||
margin: 18px 0 18px !important;
|
||||
}
|
||||
|
||||
}
|
||||
94
src/common/pages/Data/index.js
Normal file
94
src/common/pages/Data/index.js
Normal file
@@ -0,0 +1,94 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import {
|
||||
Tabs, Tab,
|
||||
} from 'material-ui';
|
||||
import {LINKS} from "../../routes";
|
||||
import '../Inbox/style.scss';
|
||||
import Categories from '../Categories';
|
||||
import StoreList from '../StoreList';
|
||||
import Tags from '../Tags';
|
||||
|
||||
export const TABS_LIST = {
|
||||
CATEGORIES: 'categories',
|
||||
STORES: 'stores',
|
||||
TAGS : 'tags'
|
||||
};
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class DataTabComponent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.taskStore = props.appstate.task;
|
||||
this.state = {
|
||||
tabSelected: TABS_LIST.STORES,
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.http = props.appstate.http;
|
||||
this.authStore = props.appstate.auth;
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
let activeTab = (this.globalUI.dataTabSelected ? this.globalUI.dataTabSelected : TABS_LIST.STORES);
|
||||
this.setState({
|
||||
tabSelected : activeTab
|
||||
});
|
||||
this.props.history.push(LINKS.DATA +`/${activeTab}`)
|
||||
}
|
||||
|
||||
handleChange = (tabSelected) => {
|
||||
this.setState({
|
||||
tabSelected: tabSelected,
|
||||
});
|
||||
this.globalUI.dataTabSelected = tabSelected;
|
||||
this.props.history.push(LINKS.DATA+'/'+tabSelected);
|
||||
};
|
||||
|
||||
getContent() {
|
||||
switch (this.state.tabSelected) {
|
||||
case TABS_LIST.STORES:
|
||||
return <StoreList/>
|
||||
case TABS_LIST.CATEGORIES:
|
||||
return <Categories/>
|
||||
case TABS_LIST.TAGS:
|
||||
return <Tags/>
|
||||
default:
|
||||
return <StoreList/>
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
<div className="inbox containerMiddle">
|
||||
<div className="row no-margin">
|
||||
<div className="col l12 m12 s12">
|
||||
<Tabs
|
||||
value={this.state.tabSelected}
|
||||
onChange={this.handleChange}
|
||||
inkBarStyle={{background: 'transparent'}}
|
||||
className="tabsAkun"
|
||||
style={{background: 'transparent'}}
|
||||
>
|
||||
<Tab label="Stores" value="stores"
|
||||
className={(this.state.tabSelected === 'stores') ? "buttonTabs buttonTabsActive" : 'buttonTabs'}>
|
||||
</Tab>
|
||||
<Tab label="Categories" value="categories"
|
||||
className={(this.state.tabSelected === 'categories') ? "buttonTabs buttonTabsActive" : 'buttonTabs'}>
|
||||
</Tab>
|
||||
<Tab label="Tags" value="tags"
|
||||
className={(this.state.tabSelected === 'tags') ? "buttonTabs buttonTabsActive" : 'buttonTabs'}>
|
||||
</Tab>
|
||||
|
||||
</Tabs>
|
||||
|
||||
{this.getContent()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
293
src/common/pages/DepositDialog/DepositForm.js
Normal file
293
src/common/pages/DepositDialog/DepositForm.js
Normal file
@@ -0,0 +1,293 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import {Dialog, Divider, FlatButton, MenuItem, RaisedButton, SelectField, TextField} from "material-ui";
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class DepositFormComponent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
openedDialogBank : false,
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.http = props.appstate.http;
|
||||
this.bankStore = props.appstate.bank;
|
||||
this.depositStore = props.appstate.deposit;
|
||||
this.currency = props.appstate.currencyStore;
|
||||
}
|
||||
|
||||
handlePaymentProof = (event, index, value) => {
|
||||
|
||||
const file = event.nativeEvent.target.files[0];
|
||||
const allowedFile = ['jpg', 'jpeg', 'png', 'gif'];
|
||||
|
||||
const [ext] = file.name.split('.').reverse();
|
||||
|
||||
if (!allowedFile.includes(ext.toLowerCase())) {
|
||||
|
||||
}
|
||||
this.depositStore.file = file.name;
|
||||
|
||||
this.http.upload(file).then((response) => {
|
||||
this.depositStore.data.payment_proof = "/api/v1" + response.path
|
||||
});
|
||||
};
|
||||
|
||||
handleOpen = () => {
|
||||
this.setState({openedDialog: true});
|
||||
};
|
||||
|
||||
handleClose = () => {
|
||||
this.setState({openedDialog: false});
|
||||
};
|
||||
|
||||
handleOpenBank = () => {
|
||||
this.setState({
|
||||
openedDialogBank:true
|
||||
})
|
||||
};
|
||||
|
||||
handleCloseBank = () => {
|
||||
this.setState({
|
||||
openedDialogBank:false
|
||||
})
|
||||
};
|
||||
|
||||
handleChangeBankName = (event) => {
|
||||
this.bankStore.data.name = event.target.value;
|
||||
};
|
||||
|
||||
handleChangeCurrency = (event, index, value) => {
|
||||
this.bankStore.data.currency_id = value.id;
|
||||
this.setState({currency: value});
|
||||
console.log(this.bankStore.data.currency_id, value)
|
||||
};
|
||||
|
||||
handleChangeOnBehalf = (event) => {
|
||||
this.bankStore.data.on_behalf = event.target.value;
|
||||
};
|
||||
|
||||
handleChangeAccount = (event) => {
|
||||
this.bankStore.data.account_number = event.target.value;
|
||||
};
|
||||
|
||||
postDataBank = () => {
|
||||
this.bankStore.post();
|
||||
this.setState({
|
||||
openedDialogBank: false,
|
||||
openedDialog:false
|
||||
});
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.bankStore.getAll();
|
||||
this.bankStore.getAdminBank();
|
||||
this.currency.getAll();
|
||||
}
|
||||
|
||||
handleBank = (event, index, value) => {
|
||||
this.depositStore.bank = value;
|
||||
this.depositStore.data.bank_name = this.depositStore.bank.name;
|
||||
this.depositStore.data.bank_account_number = this.depositStore.bank.account_number;
|
||||
this.depositStore.data.bank_behalf_of = this.depositStore.bank.on_behalf;
|
||||
}
|
||||
|
||||
handleBankAdmin = (event, index, value) => {
|
||||
this.depositStore.bankAdmin = value;
|
||||
this.depositStore.data.bank_to.id = this.depositStore.bankAdmin.id;
|
||||
this.depositStore.data.bank_to.name = this.depositStore.bankAdmin.name;
|
||||
this.depositStore.data.bank_to.account_number = this.depositStore.bankAdmin.account_number;
|
||||
this.depositStore.data.bank_to.on_behalf = this.depositStore.bankAdmin.on_behalf;
|
||||
}
|
||||
|
||||
handleAmount = (event) => {
|
||||
this.depositStore.data.amount = event.target.value;
|
||||
}
|
||||
|
||||
render() {
|
||||
const actionsBank = [
|
||||
<FlatButton
|
||||
label="No"
|
||||
primary={true}
|
||||
style={{marginRight: 10}}
|
||||
onClick={this.handleCloseBank}
|
||||
/>,
|
||||
<RaisedButton
|
||||
label="Yes"
|
||||
primary={true}
|
||||
onClick={this.handleOpen}
|
||||
/>,
|
||||
];
|
||||
const actions = [
|
||||
<FlatButton
|
||||
label="Cancel"
|
||||
primary={true}
|
||||
style={{marginRight: 10}}
|
||||
onClick={this.handleClose}
|
||||
/>,
|
||||
<RaisedButton
|
||||
label="Submit"
|
||||
primary={true}
|
||||
onClick={() => this.postDataBank()}
|
||||
/>,
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="row">
|
||||
<div className="col s12 m6 l6">
|
||||
<p style={{color: '#32325d', fontSize: '12px'}}>FROM BANK</p>
|
||||
<SelectField
|
||||
floatingLabelText={"Bank"}
|
||||
fullWidth={true}
|
||||
onChange={this.handleBank}
|
||||
value={this.depositStore.bank}
|
||||
hintText={this.depositStore.bank.name}
|
||||
>
|
||||
{this.bankStore.list.map(item => {
|
||||
return (<MenuItem key={item.id} value={item} primaryText={`Bank ${item.name}`}/>)
|
||||
})}
|
||||
<Divider/>
|
||||
<MenuItem key={0} value={0} style={{color: "blue"}} primaryText="Create New Bank.." onClick={this.handleOpenBank}/>
|
||||
</SelectField>
|
||||
<TextField
|
||||
type="text"
|
||||
fullWidth={true}
|
||||
floatingLabelText={"Bank Account Number"}
|
||||
disabled={true}
|
||||
underlineDisabledStyle={{borderBottom: '1px dotted rgba(0, 0, 0, 0.3)'}}
|
||||
value={this.depositStore.data.bank_account_number}
|
||||
/>
|
||||
<br/>
|
||||
<TextField
|
||||
type="text"
|
||||
fullWidth={true}
|
||||
floatingLabelText={"Behalf Of"}
|
||||
disabled={true}
|
||||
underlineDisabledStyle={{borderBottom: '1px dotted rgba(0, 0, 0, 0.3)'}}
|
||||
value={this.depositStore.data.bank_behalf_of}
|
||||
/>
|
||||
</div>
|
||||
<div className="col s12 m6 l6">
|
||||
<p style={{color: '#32325d', fontSize: '12px'}}>TO BANK</p>
|
||||
<SelectField
|
||||
floatingLabelText={"Bank"}
|
||||
fullWidth={true}
|
||||
value={(this.bankStore.listAdmin.length > 0) ? this.bankStore.listAdmin[0].id : 0}
|
||||
onChange={this.handleBankAdmin}
|
||||
value={this.depositStore.bankAdmin}
|
||||
>
|
||||
{this.bankStore.listAdmin.map(item => {
|
||||
return (<MenuItem key={item.id} value={item} primaryText={`Bank ${item.name}`}/>)
|
||||
})}
|
||||
</SelectField>
|
||||
<div className="listCustDetail bankDetailInformation">
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">Bank</p>
|
||||
<code
|
||||
className="listCustomerDetailItemValue">{this.depositStore.bankAdmin.name == '' ? "-" : this.depositStore.bankAdmin.name}</code>
|
||||
</div>
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">Behalf of</p>
|
||||
<p
|
||||
className="listCustomerDetailItemValue">{this.depositStore.bankAdmin.on_behalf == '' ? "--" : this.depositStore.bankAdmin.on_behalf}</p>
|
||||
</div>
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">Account Number</p>
|
||||
<p
|
||||
className="listCustomerDetailItemValue">{this.depositStore.bankAdmin.account_number == '' ? "--" : this.depositStore.bankAdmin.account_number}</p>
|
||||
</div>
|
||||
<div className="listCustDetailItem flex">
|
||||
<p className="listCustomerDetailItemKey">Currency</p>
|
||||
<p
|
||||
className="listCustomerDetailItemValue">{this.depositStore.bankAdmin.account_number == '' ? "--" : "IDR"}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col s12 m6 l6">
|
||||
<TextField fullWidth={true} min="0" type={"number"} floatingLabelText={"Amount (IDR)"}
|
||||
onChange={this.handleAmount} defaultValue={this.depositStore.data.amount}/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col s12">
|
||||
<div className="file-field input-field marginBottom18">
|
||||
<div className="btn">
|
||||
<span>File</span>
|
||||
<input type="file" onChange={(...args) => this.handlePaymentProof(...args)} accept="image/*"/>
|
||||
</div>
|
||||
<div className="file-path-wrapper">
|
||||
<input className="file-path validate" type="text"
|
||||
placeholder="Upload the evidence (jpg,jpeg,png,gif)" value={this.depositStore.file}/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Dialog
|
||||
title="Adding Bank"
|
||||
actions={actionsBank}
|
||||
modal={true}
|
||||
open={this.state.openedDialogBank}
|
||||
onRequestClose={() => this.handleCloseBank()}
|
||||
>
|
||||
<div style={{padding: 20}}>
|
||||
<div className="row">
|
||||
<div className="col s12 m6 l6">
|
||||
<p className="label-form">Name</p>
|
||||
<TextField
|
||||
hintText=" E.g. BCA"
|
||||
onChange={this.handleChangeBankName}
|
||||
fullWidth={true}
|
||||
/>
|
||||
</div>
|
||||
<div className="col s12 m6 l6">
|
||||
<p className="label-form">Currency</p>
|
||||
<SelectField
|
||||
fullWidth={true}
|
||||
value={(this.state.currency) ? this.state.currency : (() => this.setState({currency: this.currency.currencyList[0]}))}
|
||||
onChange={this.handleChangeCurrency}>
|
||||
{this.currency.currencyList.map((item, index) => {
|
||||
return (<MenuItem key={index} value={item} primaryText={item.name} />)
|
||||
})}
|
||||
</SelectField>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<div className="col s12 m6 l6">
|
||||
<p className="label-form">Account</p>
|
||||
<TextField
|
||||
hintText=" E.g. xxxxxxxxxx"
|
||||
onChange={this.handleChangeAccount}
|
||||
fullWidth={true}
|
||||
type="number"
|
||||
/>
|
||||
</div>
|
||||
<div className="col s12 m6 l6">
|
||||
<p className="label-form">On Behalf</p>
|
||||
<TextField
|
||||
hintText=" E.g. Ridwan Abadi"
|
||||
onChange={this.handleChangeOnBehalf}
|
||||
fullWidth={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
<Dialog
|
||||
title="Warning"
|
||||
actions={actions}
|
||||
modal={true}
|
||||
open={this.state.openedDialog}
|
||||
onRequestClose={() => this.handleClose()}
|
||||
>
|
||||
Make sure all of your data is correct before submitting.
|
||||
</Dialog>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
103
src/common/pages/DepositDialog/DepositReview.js
Normal file
103
src/common/pages/DepositDialog/DepositReview.js
Normal file
@@ -0,0 +1,103 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import NumberFormat from 'react-number-format';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class DepositReviewComponent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.depositStore = props.appstate.deposit;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// console.log('DepositReviewComponent loaded!', this.props)
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const {data} = this.props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
<div className="center-align"><p style={{ lineHeight: "1.6rem" }}>You will made deposit request via bank transfer</p></div>
|
||||
{/*<div className="center-align"><p style={{lineHeight:"1.6rem", marginTop:"0px", marginBottom:"0px"}}>Number: <span className="black-text">#3AB3Db</span></p></div>*/}
|
||||
<div className="center-align"><p style={{ lineHeight: "1.6rem", marginTop: "0px" }}>Date: <span className="black-text">{moment().format('DD MMMM YYYY, HH:mm:ss')}</span></p></div>
|
||||
<div className="center-align"><p style={{ lineHeight: "1.6rem", marginTop: "0px", marginBottom: "0px" }}>Total Amount</p></div>
|
||||
<div className="center-align"><h4 className="black-text" style={{ lineHeight: "1.6rem", marginTop: "0px", fontSize: "26px", marginBottom: "0px" }}><NumberFormat value={this.depositStore.data.amount} displayType={'text'} thousandSeparator={true} prefix={'IDR '} /></h4></div>
|
||||
|
||||
|
||||
<div className="row">
|
||||
<div className="col s12 m6">
|
||||
<h4 className="center-align" style={{ fontSize: '14px', marginBottom: "8px" }}>From</h4>
|
||||
<div style={{
|
||||
boxShadow: "none",
|
||||
border: "1px solid #d4d4d4",
|
||||
backgroundColor: "#f9f9f9",
|
||||
padding: "10px 10px 10px 20px",
|
||||
marginTop: 0,
|
||||
marginBottom: 0
|
||||
}} className="card-panel">
|
||||
<p className="black-text" style={{ lineHeight: '1.0rem', fontSize: 11 }}>
|
||||
Bank: {this.depositStore.bank.name}
|
||||
</p>
|
||||
<p className="black-text" style={{ lineHeight: '1.0rem', fontSize: 11 }}>
|
||||
Behalf Of: {this.depositStore.bank.on_behalf}
|
||||
</p>
|
||||
<p className="black-text" style={{ lineHeight: '1.0rem', fontSize: 11 }}>
|
||||
Account Number: {this.depositStore.bank.account_number}
|
||||
</p>
|
||||
<p className="black-text" style={{ lineHeight: '1.0rem', fontSize: 11 }}>
|
||||
Currency: IDR
|
||||
</p>
|
||||
<p className="black-text" style={{ lineHeight: '1.0rem', fontSize: 11 }}>
|
||||
Swift Code:
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div className="col s12 m6">
|
||||
<h4 className="center-align" style={{ fontSize: '14px', marginBottom: "8px" }}>To</h4>
|
||||
<div style={{
|
||||
boxShadow: "none",
|
||||
border: "1px solid #d4d4d4",
|
||||
backgroundColor: "#f9f9f9",
|
||||
padding: "10px 10px 10px 20px",
|
||||
marginTop: 0,
|
||||
marginBottom: 0
|
||||
}} className="card-panel">
|
||||
<p className="black-text" style={{ lineHeight: '1.0rem', fontSize: 11 }}>
|
||||
Bank: {this.depositStore.bankAdmin.name}
|
||||
</p>
|
||||
<p className="black-text" style={{ lineHeight: '1.0rem', fontSize: 11 }}>
|
||||
Behalf Of: {this.depositStore.bankAdmin.on_behalf}
|
||||
</p>
|
||||
<p className="black-text" style={{ lineHeight: '1.0rem', fontSize: 11 }}>
|
||||
Account Number: {this.depositStore.bankAdmin.account_number}
|
||||
</p>
|
||||
<p className="black-text" style={{ lineHeight: '1.0rem', fontSize: 11 }}>
|
||||
Currency: IDR
|
||||
</p>
|
||||
<p className="black-text" style={{ lineHeight: '1.0rem', fontSize: 11 }}>
|
||||
Swift Code: BBIJIDJA
|
||||
</p>
|
||||
{/*<p className="black-text" style={{lineHeight: '1.0rem', fontSize: 11}}>*/}
|
||||
{/*Note: [Your trading account number]*/}
|
||||
{/*</p>*/}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
226
src/common/pages/DepositDialog/index.js
Normal file
226
src/common/pages/DepositDialog/index.js
Normal file
@@ -0,0 +1,226 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import {Dialog, FlatButton, RaisedButton, Step, StepLabel, Stepper} from "material-ui";
|
||||
import {DIALOG} from "../../stores/global_ui";
|
||||
import Form from './DepositForm';
|
||||
import Review from './DepositReview';
|
||||
import get from 'lodash.get';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class DepositDialogComponent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
currentStep: 0,
|
||||
openedDialog: false,
|
||||
nextButtonText: 'Next',
|
||||
backButtonText: 'Cancel',
|
||||
formData: {},
|
||||
steps: [
|
||||
{
|
||||
label: 'Deposit Form',
|
||||
// action: () => this.validateName(),
|
||||
component: <Form/>,
|
||||
nextButtonText: 'Review',
|
||||
backButtonText: 'Cancel',
|
||||
},
|
||||
{
|
||||
label: "Review",
|
||||
component: () => <Review/>,
|
||||
// action: () => this.deposit.createDeposit(this.state.formData),
|
||||
nextButtonText: 'Deposit',
|
||||
backButtonText: 'Back',
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
this.deposit = props.appstate.deposit;
|
||||
this.transactionStore = props.appstate.transaction;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// console.log('DepositDialogComponent loaded!')
|
||||
}
|
||||
|
||||
get stepperContent() {
|
||||
const {currentStep, steps} = this.state;
|
||||
|
||||
switch (typeof steps[currentStep].component) {
|
||||
case "function":
|
||||
return steps[currentStep].component();
|
||||
default:
|
||||
return steps[currentStep].component || (<div>Step #{currentStep}</div>);
|
||||
}
|
||||
}
|
||||
|
||||
handleNext() {
|
||||
const {currentStep, steps} = this.state;
|
||||
let newStep = currentStep;
|
||||
let regex=/^[0-9]+$/;
|
||||
if(this.deposit.data.payment_proof === '' || this.deposit.data.amount === '' ||
|
||||
this.deposit.data.bank_account_number === '' || this.deposit.data.bank_name === '' ||
|
||||
this.deposit.data.bank_behalf_of === '' || this.deposit.data.bank_to.name === ''){
|
||||
this.handleOpen();
|
||||
}else if(this.deposit.data.amount.match(regex)){
|
||||
newStep = currentStep + 1;
|
||||
}else{
|
||||
this.handleOpen();
|
||||
}
|
||||
|
||||
if (newStep >= steps.length) {
|
||||
this.setState({currentStep:0});
|
||||
this.deposit.createDeposit().then(res => {
|
||||
this.globalUI.openSnackbar("Request Deposit Success");
|
||||
this.transactionStore.getAll();
|
||||
this.deposit.bankAdmin = {
|
||||
name : '',
|
||||
account_number : '',
|
||||
on_behalf : '',
|
||||
};
|
||||
this.deposit.data = {
|
||||
payment_proof: '',
|
||||
amount: '',
|
||||
bank_account_number: '',
|
||||
bank_name: '',
|
||||
bank_behalf_of: '',
|
||||
bank_to: {
|
||||
name: this.deposit.bankAdmin.name,
|
||||
account_number: this.deposit.bankAdmin.account_number,
|
||||
on_behalf: this.deposit.bankAdmin.on_behalf,
|
||||
},
|
||||
};
|
||||
});
|
||||
this.closeModal();
|
||||
}
|
||||
|
||||
(steps[currentStep].action || (() => Promise.resolve(true)))()
|
||||
.then(status => {
|
||||
this.setState({
|
||||
currentStep: newStep,
|
||||
nextButtonText: steps[newStep].nextButtonText || this.defaultState.nextButtonText,
|
||||
backButtonText: steps[newStep].backButtonText || this.defaultState.backButtonText,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
handlePrev() {
|
||||
const {currentStep, steps} = this.state;
|
||||
let newStep = currentStep - 1;
|
||||
if (newStep < 0) {
|
||||
this.setState({
|
||||
currentStep: 0,
|
||||
nextButtonText: steps[0].nextButtonText || this.defaultState.nextButtonText,
|
||||
backButtonText: steps[0].backButtonText || this.defaultState.backButtonText
|
||||
});
|
||||
this.closeModal();
|
||||
} else {
|
||||
this.setState({
|
||||
currentStep: newStep,
|
||||
nextButtonText: steps[newStep].nextButtonText || this.defaultState.nextButtonText,
|
||||
backButtonText: steps[newStep].backButtonText || this.defaultState.backButtonText,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
closeModal() {
|
||||
this.globalUI.hideDialog(DIALOG.WALLET.DEPOSIT);
|
||||
this.deposit.bankAdmin = {
|
||||
name : '',
|
||||
account_number : '',
|
||||
on_behalf : '',
|
||||
};
|
||||
this.deposit.data = {
|
||||
payment_proof: '',
|
||||
amount: '',
|
||||
bank_account_number: '',
|
||||
bank_name: '',
|
||||
bank_behalf_of: '',
|
||||
bank_to: {
|
||||
name: this.deposit.bankAdmin.name,
|
||||
account_number: this.deposit.bankAdmin.account_number,
|
||||
on_behalf: this.deposit.bankAdmin.on_behalf,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
handleClose = () => {
|
||||
this.setState({openedDialog: false})
|
||||
};
|
||||
|
||||
handleOpen = () => {
|
||||
this.setState({openedDialog: true})
|
||||
};
|
||||
|
||||
render() {
|
||||
|
||||
const actionsWarn = [
|
||||
<FlatButton
|
||||
label="Okay"
|
||||
primary={true}
|
||||
style={{marginRight:10}}
|
||||
onClick={this.handleClose}
|
||||
/>,
|
||||
];
|
||||
|
||||
let {
|
||||
currentStep,
|
||||
nextButtonText:defaultNextText,
|
||||
backButtonText:defaultBackText
|
||||
} = this.state;
|
||||
|
||||
let nextButtonText, backButtonText;
|
||||
|
||||
backButtonText = get(this.state, `steps[${currentStep}].backButtonText`, defaultBackText);
|
||||
nextButtonText = get(this.state, `steps[${currentStep}].nextButtonText`, defaultNextText);
|
||||
|
||||
const actions = [
|
||||
<FlatButton
|
||||
label={backButtonText}
|
||||
onClick={() => this.handlePrev()}
|
||||
style={{marginRight: 12}}
|
||||
/>,
|
||||
<RaisedButton
|
||||
label={nextButtonText}
|
||||
onClick={() => this.handleNext()}
|
||||
primary={true}
|
||||
/>
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Dialog
|
||||
title="Deposit Form"
|
||||
actions={actions}
|
||||
modal={true}
|
||||
onRequestClose={()=> this.closeModal()}
|
||||
autoScrollBodyContent={true}
|
||||
open={this.globalUI[DIALOG.WALLET.DEPOSIT]}>
|
||||
<Stepper activeStep={currentStep}>
|
||||
{this.state.steps.map(step => {
|
||||
return (
|
||||
<Step key={step.label}>
|
||||
<StepLabel> <span className="hide-on-small-only">{step.label}</span></StepLabel>
|
||||
</Step>
|
||||
)
|
||||
})}
|
||||
</Stepper>
|
||||
{this.stepperContent}
|
||||
</Dialog>
|
||||
<Dialog
|
||||
title="Warning"
|
||||
actions={actionsWarn}
|
||||
modal={true}
|
||||
contentStyle={{width:350}}
|
||||
open={this.state.openedDialog}
|
||||
onRequestClose={()=> this.handleClose()}
|
||||
>
|
||||
Please Fill the form correctly
|
||||
</Dialog>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
70
src/common/pages/EmptyComponent/index.js
Normal file
70
src/common/pages/EmptyComponent/index.js
Normal file
@@ -0,0 +1,70 @@
|
||||
import React from 'react';
|
||||
|
||||
export default class EmptyComponent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
const type = this.props.type;
|
||||
if(type == "empty"){
|
||||
return(
|
||||
<div style={{textAlign: 'center', padding: '20px'}}>
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css?family=Raleway');
|
||||
</style>
|
||||
<div className="row">
|
||||
<div className="col s12">
|
||||
<img src="../../../../assets/images/emptyState/default2.png" style={Object.assign({filter: "grayscale(5)"}, this.props.imageStyle || {})} width="150px" />
|
||||
</div>
|
||||
<div className="col s12" style={{marginTop: '0px'}}>
|
||||
<h1>{this.props.header}</h1>
|
||||
<h3 style={{marginTop: '10px', color: '#808080', fontFamily: 'Raleway, sans-serif'}}>{this.props.content}</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
else if(type == "default3"){
|
||||
return(
|
||||
<div style={{textAlign: 'center', padding: '20px'}}>
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css?family=Raleway');
|
||||
</style>
|
||||
<div className="row">
|
||||
<div className="col s12">
|
||||
<img src="../../../../assets/images/emptyState/default3.png" style={{filter: "grayscale(5)"}} width="250px" />
|
||||
</div>
|
||||
<div className="col s12" style={{marginTop: '0px'}}>
|
||||
<h1>{this.props.header}</h1>
|
||||
<h3 style={{marginTop: '10px', color: '#808080', fontFamily: 'Raleway, sans-serif'}}>{this.props.content}</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
else if(type == "404"){
|
||||
return(
|
||||
<div style={{textAlign: 'center', padding: '20px'}}>
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css?family=Raleway');
|
||||
</style>
|
||||
<div className="row">
|
||||
<div className="col m12">
|
||||
<img src="../../../../assets/images/emptyState/404.png" width="600px" />
|
||||
</div>
|
||||
<div className="col m12">
|
||||
<h1>{this.props.header}</h1>
|
||||
<h3 style={{marginTop: '10px', color: '#808080', fontFamily: 'Raleway, sans-serif'}}>{this.props.content}</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
36
src/common/pages/EmptyState/index.js
Normal file
36
src/common/pages/EmptyState/index.js
Normal file
@@ -0,0 +1,36 @@
|
||||
import React from 'react';
|
||||
|
||||
import './style.scss';
|
||||
|
||||
export default class EmptyStateComponent extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
uniqId: (this.props.key) ? this.props.key : (new Date).getTime()
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
console.log(this.props);
|
||||
|
||||
const ele = document.getElementById(this.state.uniqId);
|
||||
|
||||
ele.style.top = (ele.clientHeight / 2) + 'px;'
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="empty-state">
|
||||
<div id={this.state.uniqId} className="message-container">
|
||||
<img src="https://www.gstatic.com/mobilesdk/160505_mobilesdk/zerostate/2x/storage.png" alt="Empty" height="100" />
|
||||
<br/>
|
||||
{this.props.message}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
9
src/common/pages/EmptyState/style.scss
Normal file
9
src/common/pages/EmptyState/style.scss
Normal file
@@ -0,0 +1,9 @@
|
||||
.empty-state {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
|
||||
.message-container {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
305
src/common/pages/Entities/index.js
Normal file
305
src/common/pages/Entities/index.js
Normal file
@@ -0,0 +1,305 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import {
|
||||
Card,
|
||||
CardActions,
|
||||
CardHeader,
|
||||
CardMedia,
|
||||
CardTitle,
|
||||
AutoComplete,
|
||||
CardText,
|
||||
FlatButton,
|
||||
List,
|
||||
ListItem,
|
||||
Divider,
|
||||
Snackbar,
|
||||
Tabs, Tab,
|
||||
RaisedButton,
|
||||
Toolbar,
|
||||
DatePicker,
|
||||
FontIcon,
|
||||
Table,
|
||||
TableBody,
|
||||
TableHeader,
|
||||
TableHeaderColumn,
|
||||
TableRow,
|
||||
TableRowColumn,
|
||||
MenuItem,
|
||||
Toggle,
|
||||
ToolbarGroup,
|
||||
FloatingActionButton,
|
||||
ToolbarSeparator,
|
||||
IconButton,
|
||||
ToolbarTitle,
|
||||
RadioButton,
|
||||
TextField,
|
||||
Paper,
|
||||
RadioButtonGroup,Dialog
|
||||
} from 'material-ui';
|
||||
|
||||
import ContentAdd from 'material-ui/svg-icons/content/add';
|
||||
import { Modal, Button } from 'antd';
|
||||
import {yellow500} from 'material-ui/styles/colors';
|
||||
import StarBorder from 'material-ui/svg-icons/toggle/star-border';
|
||||
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/action/delete';
|
||||
import ImageEdit from 'material-ui/svg-icons/image/edit';
|
||||
import EmptyComponent from '../EmptyComponent';
|
||||
import {Link} from 'react-router-dom';
|
||||
import {LINKS} from "../../routes";
|
||||
// import './style.scss';
|
||||
import {appConfig} from "../../config/app";
|
||||
import NumberFormat from 'react-number-format';
|
||||
import LoadingDialog from "../LoadingDialog";
|
||||
import Loader from 'react-loader-advanced';
|
||||
const styles = {
|
||||
smallIcon: {
|
||||
width: 36,
|
||||
height: 36,
|
||||
},
|
||||
mediumIcon: {
|
||||
width: 48,
|
||||
height: 48,
|
||||
},
|
||||
largeIcon: {
|
||||
width: 60,
|
||||
height: 60,
|
||||
},
|
||||
small: {
|
||||
width: 72,
|
||||
height: 72,
|
||||
padding: 16,
|
||||
},
|
||||
medium: {
|
||||
width: 96,
|
||||
height: 96,
|
||||
padding: 24,
|
||||
},
|
||||
large: {
|
||||
width: 120,
|
||||
height: 120,
|
||||
padding: 30,
|
||||
},
|
||||
};
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class StoreComponent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.entitiesStore = props.appstate.entities;
|
||||
this.state = {
|
||||
snackbarOpen: false,
|
||||
snackbarMessage: '',
|
||||
entity : '',
|
||||
visible: false,
|
||||
openedDialog:false
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.http = props.appstate.http;
|
||||
this.authStore = props.appstate.auth;
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.globalUI.openLoading();
|
||||
this.entitiesStore.getAll().then(res => {
|
||||
console.log(res,"res");
|
||||
this.globalUI.closeLoading();
|
||||
this.setState({items:res})
|
||||
});
|
||||
// setTimeout(() => this.globalUI.closeLoading(), 1500);
|
||||
}
|
||||
|
||||
showModal = () => {
|
||||
this.setState({
|
||||
visible: true,
|
||||
});
|
||||
}
|
||||
hideModal = () => {
|
||||
this.setState({
|
||||
visible: false,
|
||||
});
|
||||
}
|
||||
|
||||
openModal = () => {
|
||||
this.setState({
|
||||
openedDialog:true
|
||||
})
|
||||
}
|
||||
|
||||
closeModal = () => {
|
||||
this.setState({
|
||||
openedDialog:false
|
||||
})
|
||||
}
|
||||
|
||||
handleAccept = () => {
|
||||
// this.setState({
|
||||
// expanded: 'x!0-2#',
|
||||
// snackbarMessage: 'Input Accepted',
|
||||
// snackbarOpen: true,
|
||||
// });
|
||||
console.log(this.state.entity);
|
||||
if(this.state.entity == ""){
|
||||
this.setState({
|
||||
visible: true
|
||||
})
|
||||
console.log('kosong')
|
||||
}
|
||||
else {
|
||||
console.log('data');
|
||||
this.entitiesStore.create({name:this.state.entity}).then(res=>{
|
||||
console.log(this.state.entity);
|
||||
this.globalUI.openSnackbar("Success Added New Admin");
|
||||
this.setState({
|
||||
openedDialog:false
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
handleDecline = (task) => {
|
||||
this.setState({
|
||||
expanded: 'x!0-2#',
|
||||
snackbarMessage: task + ' Declined',
|
||||
snackbarOpen: true,
|
||||
})
|
||||
};
|
||||
|
||||
handleClose = () => {
|
||||
this.setState({
|
||||
snackbarOpen: false
|
||||
})
|
||||
};
|
||||
|
||||
// handleChange = (event, index) => this.setState({entity:event.target.value});
|
||||
|
||||
handleChange = (event) => {
|
||||
this.setState({
|
||||
entity: event.target.value,
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
|
||||
const actions = [
|
||||
<FlatButton
|
||||
label="Cancel"
|
||||
primary={true}
|
||||
style={{marginRight: 10}}
|
||||
onClick={this.closeModal}
|
||||
/>,
|
||||
<RaisedButton
|
||||
label="New Entity"
|
||||
primary={true}
|
||||
onClick={() => this.handleAccept()}
|
||||
/>,
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="member containerMiddle">
|
||||
<div style={{marginBottom: '16px'}}>
|
||||
<h3 className="headerMenu">Entities</h3>
|
||||
</div>
|
||||
<Card className="animated fadeIn cardLite">
|
||||
<Toolbar className="toolbarCard" style={{backgroundColor: '#fff'}}>
|
||||
<ToolbarGroup>
|
||||
<SearchIcon style={{marginRight: 8, color: "#999"}}/>
|
||||
<TextField
|
||||
hintText="Search All"
|
||||
style={{fontSize: 14}}
|
||||
hintStyle={{fontSize: 14}}
|
||||
underlineShow={false}
|
||||
/>
|
||||
{/*<TextField*/}
|
||||
{/*hintText="Input New Entity"*/}
|
||||
{/*style={{fontSize: 14}}*/}
|
||||
{/*value={this.state.entity}*/}
|
||||
{/*hintStyle={{fontSize: 14}}*/}
|
||||
{/*underlineShow={false}*/}
|
||||
{/*onChange={this.handleChange}*/}
|
||||
{/*/>*/}
|
||||
{/*<IconButton*/}
|
||||
{/*onClick={this.handleAccept}>*/}
|
||||
{/*<AddIcon />*/}
|
||||
{/*</IconButton>*/}
|
||||
</ToolbarGroup>
|
||||
<ToolbarGroup className="ToolbarGroupLast">
|
||||
<ToolbarSeparator/>
|
||||
<RaisedButton className="ToolbarGroupLastButton" primary={true} onClick={this.openModal} icon={<AddIcon/>}
|
||||
label="New Entity"/>
|
||||
</ToolbarGroup>
|
||||
</Toolbar>
|
||||
<Divider/>
|
||||
<div>
|
||||
<Loader show={this.globalUI.loadingVisibility} message={<LoadingDialog />} messageStyle={{textAlign:'center'}} backgroundStyle={{backgroundColor: 'rgba(255,255,255,0.5)'}}>
|
||||
<Table selectable={false}>
|
||||
<TableHeader displaySelectAll={false}
|
||||
adjustForCheckbox={false}
|
||||
enableSelectAll={false}>
|
||||
<TableRow style={{height:38, background:'#f6f9fc'}}>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun" style={{height:'auto'}}>No.</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun" style={{height:'auto'}}>Entity</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun" style={{height:'auto'}}>Date</TableHeaderColumn>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody displayRowCheckbox={false}>
|
||||
{
|
||||
(!this.entitiesStore.isEmpty) ?
|
||||
this.entitiesStore.entities.map((item, index) => {
|
||||
return (
|
||||
<TableRow>
|
||||
<TableRowColumn>{index+1}</TableRowColumn>
|
||||
<TableRowColumn>{item.name}</TableRowColumn>
|
||||
<TableRowColumn>{moment(item.created_at).format('MMMM Do YYYY, H:mm:ss')}</TableRowColumn>
|
||||
</TableRow>
|
||||
);
|
||||
}) : <EmptyComponent type="empty" header="" content="There is no data in sight"/>
|
||||
}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</Loader>
|
||||
</div>
|
||||
</Card>
|
||||
<Modal
|
||||
title="Modal"
|
||||
visible={this.state.visible}
|
||||
onOk={this.hideModal}
|
||||
zIndex={1000000}
|
||||
footer={[
|
||||
<Button key="Ok" type="primary" onClick={this.hideModal}>
|
||||
Submit
|
||||
</Button>,
|
||||
]}
|
||||
>
|
||||
<p>Your Data is empty</p>
|
||||
</Modal>
|
||||
<Dialog
|
||||
modal={true}
|
||||
open={this.state.openedDialog}
|
||||
actions={actions}
|
||||
>
|
||||
<div style={{padding: 20}}>
|
||||
|
||||
<div className="row">
|
||||
<div className="col s12 m6 l6">
|
||||
<p className="label-form">First Name</p>
|
||||
<TextField
|
||||
hintText="Asa Creative"
|
||||
style={{fontSize: 14}}
|
||||
value={this.state.entity}
|
||||
onChange={this.handleChange} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</Dialog>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
146
src/common/pages/FeaturedCategory/Dialog/FeaturedCategoryData.js
Normal file
146
src/common/pages/FeaturedCategory/Dialog/FeaturedCategoryData.js
Normal file
@@ -0,0 +1,146 @@
|
||||
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 } 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';
|
||||
|
||||
const InputGroup = Input.Group;
|
||||
const { TextArea } = Input;
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class FeaturedCategoryData extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
dataSource: [],
|
||||
formData: Object.assign({
|
||||
name : '',
|
||||
icon : '',
|
||||
background_image : ''
|
||||
},props.defaultValue ) || {},
|
||||
checked: true,
|
||||
errorText: {},
|
||||
onChangeTimeoutId: false,
|
||||
|
||||
};
|
||||
this.categoryStore = props.appstate.category;
|
||||
this.http = props.appstate.http;
|
||||
}
|
||||
|
||||
// componentWillUnmount(){
|
||||
|
||||
// }
|
||||
|
||||
async componentDidMount() {
|
||||
const {defaultValue={},mode} = this.props;
|
||||
await this.categoryStore.getCategoryList();
|
||||
}
|
||||
|
||||
|
||||
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],
|
||||
onNewRequest: (v) => {
|
||||
this.setState({
|
||||
formData: {
|
||||
...this.state.formData,
|
||||
[key]: v.id,
|
||||
}
|
||||
}, () => this.triggerOnChange(key));
|
||||
}
|
||||
});
|
||||
|
||||
const {mode="create"} = this.props;
|
||||
const dataSourceConfig = {
|
||||
text: 'name',
|
||||
value: 'id',
|
||||
};
|
||||
return(
|
||||
<div style={{marginTop: 10}}>
|
||||
<div className={"row"}>
|
||||
<div className={"col s12"}>
|
||||
<div>
|
||||
<p className="label-form">Item Name</p>
|
||||
{wrapperAutocomplete("category_id")(
|
||||
<AutoComplete
|
||||
hintText="E.g. Fashion Pria"
|
||||
dataSource={this.categoryStore.categoryList.slice()}
|
||||
filter={AutoComplete.fuzzyFilter}
|
||||
dataSourceConfig={dataSourceConfig}
|
||||
openOnFocus={true}
|
||||
fullWidth={true}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
261
src/common/pages/FeaturedCategory/Dialog/index.js
Normal file
261
src/common/pages/FeaturedCategory/Dialog/index.js
Normal file
@@ -0,0 +1,261 @@
|
||||
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 FeaturedCategoryData from './FeaturedCategoryData';
|
||||
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 FeaturedCategoryDialog extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
stepIndex: 0,
|
||||
formData: {},
|
||||
finished: false,
|
||||
openedDialog: false,
|
||||
formData: {},
|
||||
errorMessage: ''
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
this.customer = props.appstate.customer;
|
||||
this.featured = props.appstate.featured_category;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.setState({
|
||||
stepIndex: 0
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
onChangeForm(formData) {
|
||||
this.setState({formData});
|
||||
}
|
||||
|
||||
getStepContent(stepIndex) {
|
||||
|
||||
const {mode="create", defaultValue={}} = this.props;
|
||||
|
||||
switch (stepIndex) {
|
||||
case 0:
|
||||
return (
|
||||
<FeaturedCategoryData
|
||||
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 = {
|
||||
category_id: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Please Select the Category'
|
||||
}
|
||||
],
|
||||
};
|
||||
|
||||
const validator = new schema(rules);
|
||||
|
||||
validator.validate(this.state.formData, (errs, f) => {
|
||||
console.log(errs);
|
||||
if (errs) {
|
||||
this.globalUI.showNotification("Something's Wrong", errs[0].message);
|
||||
} else {
|
||||
this.setState({
|
||||
stepIndex: stepIndex + 1,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
handlePrev = () => {
|
||||
const {stepIndex} = this.state;
|
||||
if (stepIndex > 0) {
|
||||
this.setState({stepIndex: stepIndex - 1});
|
||||
}
|
||||
};
|
||||
|
||||
closeDialog = ()=>{
|
||||
this.featured.formData.category_id = "";
|
||||
this.globalUI.hideDialog(DIALOG.FEATURED_CATEGORIES.CREATE)
|
||||
}
|
||||
|
||||
handleClose = () => {
|
||||
this.setState({confirmationDialog: false})
|
||||
};
|
||||
|
||||
save = () => {
|
||||
this.globalUI.hideDialog(DIALOG.FEATURED_CATEGORIES.CREATE);
|
||||
this.globalUI.showDialogLoading();
|
||||
const {mode="create", defaultValue={}} = this.props;
|
||||
|
||||
if (mode === "create") {
|
||||
let data = this.state.formData;
|
||||
this.featured.create(data)
|
||||
.then(res => {
|
||||
this.globalUI.hideDialogLoading();
|
||||
this.globalUI.openSnackbar("Success Added New Featured Category");
|
||||
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") {
|
||||
let data = this.state.formData;
|
||||
|
||||
this.featured.put(defaultValue.id, this.featured.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") ? "Choose" : "Update"} Category</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"}}>Category 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.FEATURED_CATEGORIES.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>
|
||||
)
|
||||
}
|
||||
}
|
||||
256
src/common/pages/FeaturedCategory/index.js
Normal file
256
src/common/pages/FeaturedCategory/index.js
Normal file
@@ -0,0 +1,256 @@
|
||||
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 ImageEdit from 'material-ui/svg-icons/image/edit';
|
||||
import EmptyComponent from '../EmptyComponent';
|
||||
import LoadingDialog from "../LoadingDialog";
|
||||
import Loader from 'react-loader-advanced';
|
||||
import {appConfig} from "../../config/app";
|
||||
import {Link} from 'react-router-dom';
|
||||
import {LINKS} from "../../routes";
|
||||
import moment from 'moment';
|
||||
import {DIALOG} from "../../stores/global_ui";
|
||||
import DialogCreate from './Dialog';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class FeaturedCategory extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
value: 0,
|
||||
edit : false,
|
||||
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.featured = props.appstate.featured_category;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.globalUI.openLoading();
|
||||
this.featured.getAll().then(res=>{
|
||||
this.globalUI.closeLoading();
|
||||
}).catch(err=>{
|
||||
this.globalUI.closeLoading();
|
||||
});
|
||||
}
|
||||
|
||||
handleUpdateInput = (searchText) => {
|
||||
this.setState({
|
||||
searchText: searchText,
|
||||
});
|
||||
};
|
||||
|
||||
handleNewRequest = () => {
|
||||
this.setState({
|
||||
searchText: '',
|
||||
});
|
||||
};
|
||||
|
||||
tabsHandleChange = (value) => {
|
||||
this.setState({
|
||||
slideIndex: value,
|
||||
});
|
||||
};
|
||||
|
||||
deleteClicked = (id) => {
|
||||
this.setState({
|
||||
id : id,
|
||||
openedDelete: true
|
||||
});
|
||||
}
|
||||
|
||||
editData = (index)=>{
|
||||
this.setState({
|
||||
edit : true,
|
||||
defaultValue : this.featured_category.data[index]
|
||||
},()=>{
|
||||
this.globalUI.showDialog(DIALOG.FEATURED_CATEGORIES.CREATE);
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
handleOpenDialog = () => {
|
||||
this.setState({
|
||||
edit : false
|
||||
})
|
||||
this.globalUI.showDialog(DIALOG.FEATURED_CATEGORIES.CREATE);
|
||||
}
|
||||
|
||||
handleClickDelete = (id) => {
|
||||
this.featured.delete(id).then(res=>{
|
||||
this.featured.getAll();
|
||||
this.setState({
|
||||
openedDelete: false,
|
||||
openSnackbarDelete: true
|
||||
});
|
||||
this.globalUI.openSnackbar("Successful Deleted Existing Featured Category");
|
||||
|
||||
}).catch(err=>{
|
||||
console.log(err);
|
||||
this.globalUI.openSnackbar(err.message);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
handleCloseDelete = () => {
|
||||
this.setState({
|
||||
openedDelete: false
|
||||
})
|
||||
}
|
||||
|
||||
search = (event)=>{
|
||||
if(event.target.value.length == 0){
|
||||
this.featured.isSearching = false;
|
||||
}
|
||||
else{
|
||||
this.featured.isSearching = true;
|
||||
this.featured.search(event.target.value);
|
||||
}
|
||||
}
|
||||
|
||||
handleChange = (event, index, value) => this.setState({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 Featured Categories"
|
||||
style={{fontSize: 14}}
|
||||
hintStyle={{fontSize: 14}}
|
||||
underlineShow={false}
|
||||
onChange={this.search}
|
||||
/>
|
||||
</ToolbarGroup>
|
||||
<ToolbarGroup className="ToolbarGroupLast">
|
||||
<ToolbarSeparator/>
|
||||
<RaisedButton className="ToolbarGroupLastButton" icon={<AddIcon/>} label="New Category"
|
||||
primary={true} onClick={this.handleOpenDialog}/>
|
||||
</ToolbarGroup>
|
||||
</Toolbar>
|
||||
<Divider/>
|
||||
<div style={{paddingBottom: 5}}>
|
||||
<Loader show={this.globalUI.loadingVisibility} message={<LoadingDialog/>}
|
||||
messageStyle={{textAlign: 'center'}} backgroundStyle={{backgroundColor: 'rgba(255,255,255,0.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', textAlign: 'right'}}>Action</TableHeaderColumn>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody displayRowCheckbox={false}>
|
||||
{(!this.featured.isEmpty) ? (this.featured.isSearching ? this.featured.dataFiltered : this.featured.data).map((item, index) => {
|
||||
return (
|
||||
<TableRow key={item.id}>
|
||||
<TableRowColumn>
|
||||
<div style={{color : '#6772e5',cursor : 'pointer'}} onClick={()=>this.handleOpenEdit(item.id)}>
|
||||
{item.name}
|
||||
</div>
|
||||
</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>
|
||||
</Loader>
|
||||
</div>
|
||||
<Dialog
|
||||
title="Warning"
|
||||
actions={actionsDelete}
|
||||
modal={true}
|
||||
open={this.state.openedDelete}
|
||||
onRequestClose={() => this.handleCloseDelete()}
|
||||
>
|
||||
Are you sure want to delete this data?
|
||||
</Dialog>
|
||||
{this.state.edit ? <DialogCreate mode="update" defaultValue={Object.assign({},this.state.defaultValue)}/> : <DialogCreate mode="create"/>}
|
||||
|
||||
</Card>
|
||||
|
||||
)
|
||||
}
|
||||
}
|
||||
284
src/common/pages/FeaturedItems/Dialog/CategoryData.js
Normal file
284
src/common/pages/FeaturedItems/Dialog/CategoryData.js
Normal file
@@ -0,0 +1,284 @@
|
||||
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 } 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';
|
||||
|
||||
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 = {
|
||||
type:1,
|
||||
dataSource: [],
|
||||
formData: Object.assign({
|
||||
type:'',
|
||||
value_id:null,
|
||||
image:'',
|
||||
link_target:''
|
||||
},props.defaultValue ) || {},
|
||||
checked: true,
|
||||
errorText: {},
|
||||
onChangeTimeoutId: false,
|
||||
previewVisible : '',
|
||||
previewImage : '',
|
||||
fileList : '',
|
||||
previewVisibleBackground : '',
|
||||
previewImageBackground : '',
|
||||
fileListBackground : '',
|
||||
};
|
||||
this.item = props.appstate.item;
|
||||
this.http = props.appstate.http;
|
||||
this.featured = props.appstate.featuredClass;
|
||||
}
|
||||
|
||||
// componentWillUnmount(){
|
||||
|
||||
// }
|
||||
|
||||
async componentDidMount() {
|
||||
const {defaultValue={},mode} = this.props;
|
||||
await this.item.getAll();
|
||||
// this.setState({
|
||||
// formData : this.featured.formData
|
||||
// },()=>this.triggerOnChange(2));
|
||||
|
||||
|
||||
// if(mode == "update"){
|
||||
// await this.featured.getDetail(this.props.defaultValue.id)
|
||||
// }
|
||||
|
||||
// if(defaultValue.image != ""){
|
||||
// let file = defaultValue.image.split("/");
|
||||
// this.setState({
|
||||
// fileListBanner : [{
|
||||
// uid: file[2],
|
||||
// name: file[2],
|
||||
// status: 'done',
|
||||
// url: this.http.appendImagePath(defaultValue.image),
|
||||
// path: defaultValue.image,
|
||||
// type: 'main'
|
||||
// }]
|
||||
// })
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
handleCancelBackground = () => this.setState({ previewVisibleBackground: false });
|
||||
handleChangeBackground = ({ fileList }) => {
|
||||
this.setState({ fileListBackground : fileList });
|
||||
console.log(fileList, 'remove')
|
||||
if(fileList.length == 0){
|
||||
this.setState({
|
||||
formData : {
|
||||
...this.state.formData,
|
||||
image : ''
|
||||
}
|
||||
},()=>this.triggerOnChange(2))
|
||||
}
|
||||
};
|
||||
|
||||
uploaderHandlerBackground({file, onProgress}) {
|
||||
this.http.upload(file)
|
||||
.then(res => {
|
||||
const {fileListBackground} = this.state;
|
||||
let newFileList = fileListBackground.filter((obj) => {
|
||||
if (!obj.lastModified) {
|
||||
return true;
|
||||
}
|
||||
|
||||
})
|
||||
newFileList.push({
|
||||
uid: newFileList.length,
|
||||
name: file.name,
|
||||
status: 'done',
|
||||
url: this.http.appendImagePath(res.path),
|
||||
path: res.path,
|
||||
type: 'main'
|
||||
});
|
||||
|
||||
this.setState({
|
||||
fileListBackground: newFileList,
|
||||
formData: {
|
||||
...this.state.formData,
|
||||
image: res.path
|
||||
}
|
||||
}, () => this.triggerOnChange(2));
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
triggerOnChange(key) {
|
||||
this.props.onChangeData(this.state.formData);
|
||||
}
|
||||
|
||||
updateCheck() {
|
||||
this.setState((oldState) => {
|
||||
return {
|
||||
checked: !oldState.checked,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
handleChangeType = (event, index, value) => {
|
||||
this.setState({
|
||||
formData : {
|
||||
...this.state.formData,
|
||||
type:value
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
render() {
|
||||
const { previewVisible, previewImage, fileList,previewVisibleBackground, previewImageBackground, fileListBackground } = this.state;
|
||||
|
||||
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],
|
||||
onNewRequest: (v) => {
|
||||
this.setState({
|
||||
formData: {
|
||||
...this.state.formData,
|
||||
[key]: v.id,
|
||||
}
|
||||
}, () => this.triggerOnChange(key));
|
||||
}
|
||||
});
|
||||
|
||||
const {mode="create"} = this.props;
|
||||
const dataSourceConfig = {
|
||||
text: 'name',
|
||||
value: 'id',
|
||||
};
|
||||
|
||||
const uploadButton = (
|
||||
<div>
|
||||
<Icon type="plus" />
|
||||
<div className="ant-upload-text">Upload</div>
|
||||
</div>
|
||||
);
|
||||
return(
|
||||
<div style={{marginTop: 10}}>
|
||||
<div className={"row"}>
|
||||
<div className={"col s12"}>
|
||||
<p className="label-form">Choose Type Banner</p>
|
||||
{wrapperSelect("type")(
|
||||
<SelectField
|
||||
//value={this.state.formData.type}
|
||||
//onChange={this.handleChangeType}
|
||||
>
|
||||
<MenuItem value={'items'} primaryText="Item" />
|
||||
<MenuItem value={'link'} primaryText="Banner" />
|
||||
</SelectField>)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={"row"}>
|
||||
{(this.state.formData.type === "items") ? (
|
||||
<div className={"col s12"}>
|
||||
<div>
|
||||
<p className="label-form">Item Name</p>
|
||||
{wrapperAutocomplete("value_id")(
|
||||
<AutoComplete
|
||||
hintText="E.g. T-Shirt"
|
||||
dataSource={this.item.data.slice()}
|
||||
filter={AutoComplete.fuzzyFilter}
|
||||
dataSourceConfig={dataSourceConfig}
|
||||
openOnFocus={true}
|
||||
fullWidth={true}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
) : ""}
|
||||
|
||||
{ (this.state.formData.type === "link") ?
|
||||
(
|
||||
<div>
|
||||
<div className={"col s12 m6 l6"}>
|
||||
<p className="label-form" onClick={()=>console.log(this.state.formData)}>Banner</p>
|
||||
<Upload
|
||||
listType="picture-card"
|
||||
fileList={fileListBackground}
|
||||
customRequest={(...args) => this.uploaderHandlerBackground(...args)}
|
||||
style={{}}
|
||||
onChange={this.handleChangeBackground}
|
||||
>
|
||||
{fileListBackground.length == 1 ? null : uploadButton}
|
||||
</Upload>
|
||||
<Modal visible={previewVisibleBackground} footer={null} onCancel={this.handleCancelBackground}>
|
||||
<img alt="example" style={{ width: '100%' }} src={previewImageBackground} />
|
||||
</Modal>
|
||||
</div>
|
||||
<div className={"col s12 m6 l6"}>
|
||||
<p className="label-form">Hyperlink (optional)</p>
|
||||
{wrapperText("link_target")(
|
||||
<TextField
|
||||
fullWidth={true}
|
||||
hintText="Link target, use http:// or https://"/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
) : ""
|
||||
}
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
301
src/common/pages/FeaturedItems/Dialog/index.js
Normal file
301
src/common/pages/FeaturedItems/Dialog/index.js
Normal file
@@ -0,0 +1,301 @@
|
||||
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.customer = props.appstate.customer;
|
||||
this.featured = props.appstate.featured_item;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
console.log(this.state.formData,'ini men');
|
||||
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(this.state.formData.type == 'items') {
|
||||
if (stepIndex === 0) {
|
||||
|
||||
const rules = {
|
||||
value_id: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Please Select the Item'
|
||||
}
|
||||
],
|
||||
};
|
||||
|
||||
const validator = new schema(rules);
|
||||
|
||||
validator.validate(this.state.formData, (errs, f) => {
|
||||
console.log(this.state.formData.type,'ini loh 1');
|
||||
if (errs) {
|
||||
this.globalUI.showNotification("Something's Wrong", errs[0].message);
|
||||
} else {
|
||||
this.setState({
|
||||
stepIndex: stepIndex + 1,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (stepIndex === 0) {
|
||||
|
||||
const rules = {
|
||||
image: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Please insert image banner'
|
||||
}
|
||||
],
|
||||
};
|
||||
|
||||
const validator = new schema(rules);
|
||||
validator.validate(this.state.formData, (errs, f) => {
|
||||
if (errs) {
|
||||
this.globalUI.showNotification("Something's Wrong", errs[0].message);
|
||||
} else {
|
||||
if(!!this.state.formData.link_target){
|
||||
let regex=/(https?:\/\/[^\s]+)/;
|
||||
if(this.state.formData.link_target.match(regex)){
|
||||
this.setState({
|
||||
stepIndex: stepIndex + 1,
|
||||
});
|
||||
}
|
||||
else{
|
||||
this.globalUI.showNotification("Something's Wrong in hyperlink");
|
||||
}
|
||||
}else{
|
||||
this.setState({
|
||||
stepIndex: stepIndex + 1,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
handlePrev = () => {
|
||||
const {stepIndex} = this.state;
|
||||
if (stepIndex > 0) {
|
||||
this.setState({stepIndex: stepIndex - 1});
|
||||
}
|
||||
};
|
||||
|
||||
closeDialog = ()=>{
|
||||
this.featured.formData.item_id = "";
|
||||
this.globalUI.hideDialog(DIALOG.FEATURED_ITEM.CREATE)
|
||||
}
|
||||
|
||||
handleClose = () => {
|
||||
this.setState({confirmationDialog: false})
|
||||
};
|
||||
|
||||
save = () => {
|
||||
this.globalUI.hideDialog(DIALOG.FEATURED_ITEM.CREATE);
|
||||
this.globalUI.showDialogLoading();
|
||||
const {mode="create", defaultValue={}} = this.props;
|
||||
|
||||
if (mode === "create") {
|
||||
let data = this.state.formData;
|
||||
this.featured.create(data)
|
||||
.then(res => {
|
||||
this.globalUI.hideDialogLoading();
|
||||
this.globalUI.openSnackbar("Success Added New Banner");
|
||||
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") {
|
||||
let data = this.state.formData;
|
||||
|
||||
this.featured.put(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"} Banner</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"}}>Banner 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.FEATURED_ITEM.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>
|
||||
)
|
||||
}
|
||||
}
|
||||
236
src/common/pages/FeaturedItems/index.js
Normal file
236
src/common/pages/FeaturedItems/index.js
Normal file
@@ -0,0 +1,236 @@
|
||||
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 ImageEdit from 'material-ui/svg-icons/image/edit';
|
||||
import EmptyComponent from '../EmptyComponent';
|
||||
import LoadingDialog from "../LoadingDialog";
|
||||
import Loader from 'react-loader-advanced';
|
||||
import {appConfig} from "../../config/app";
|
||||
import {Link} from 'react-router-dom';
|
||||
import {LINKS} from "../../routes";
|
||||
import {DIALOG} from "../../stores/global_ui";
|
||||
import DialogCreate from './Dialog';
|
||||
import get from 'lodash.get'
|
||||
|
||||
|
||||
|
||||
|
||||
let DateTimeFormat = global.Intl.DateTimeFormat;
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class FeaturedItems 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.featured = props.appstate.featured_item;
|
||||
this.item = props.appstate.item;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.globalUI.openLoading();
|
||||
this.featured.getAll().then(res=>{
|
||||
this.globalUI.closeLoading();
|
||||
}).catch(err=>{
|
||||
this.globalUI.closeLoading();
|
||||
});
|
||||
this.item.getAll();
|
||||
}
|
||||
|
||||
deleteClicked = (id) => {
|
||||
this.setState({
|
||||
id : id,
|
||||
openedDelete: true
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
handleOpenDialog = (mode,Id) => {
|
||||
this.setState({
|
||||
mode : mode,
|
||||
defaultValue : (Id == null) ? {} : {
|
||||
id : Id
|
||||
}
|
||||
},()=>this.globalUI.showDialog(DIALOG.FEATURED_ITEM.CREATE));
|
||||
};
|
||||
|
||||
handleClickDelete = (id) => {
|
||||
this.featured.delete(id).then(res=>{
|
||||
this.featured.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.featured.isSearching = false;
|
||||
}
|
||||
else{
|
||||
this.featured.isSearching = true;
|
||||
this.featured.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 Banner"
|
||||
style={{fontSize: 14}}
|
||||
hintStyle={{fontSize: 14}}
|
||||
underlineShow={false}
|
||||
onChange={this.search}
|
||||
/>
|
||||
</ToolbarGroup>
|
||||
<ToolbarGroup className="ToolbarGroupLast">
|
||||
<ToolbarSeparator/>
|
||||
<RaisedButton className="ToolbarGroupLastButton" icon={<AddIcon/>} label="New Banner"
|
||||
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', textAlign: 'right'}}>Action</TableHeaderColumn>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody displayRowCheckbox={false}>
|
||||
{(!this.featured.isEmpty) ? (this.featured.isSearching ? this.featured.dataFiltered : this.featured.data).map((item, index) => {
|
||||
return (
|
||||
<TableRow key={item.id}>
|
||||
<TableRowColumn>
|
||||
<div style={{color : '#6772e5',cursor : 'pointer'}}>
|
||||
{(item.link_target === "") ? item.name : item.link_target}
|
||||
</div>
|
||||
</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>
|
||||
)
|
||||
}
|
||||
}
|
||||
146
src/common/pages/FeaturedStores/Dialog/FeaturedStoresData.js
Normal file
146
src/common/pages/FeaturedStores/Dialog/FeaturedStoresData.js
Normal file
@@ -0,0 +1,146 @@
|
||||
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 } 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';
|
||||
|
||||
const InputGroup = Input.Group;
|
||||
const { TextArea } = Input;
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class FeaturedStoresData extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
dataSource: [],
|
||||
formData: Object.assign({
|
||||
name : '',
|
||||
icon : '',
|
||||
background_image : ''
|
||||
},props.defaultValue ) || {},
|
||||
checked: true,
|
||||
errorText: {},
|
||||
onChangeTimeoutId: false,
|
||||
|
||||
};
|
||||
this.store = props.appstate.storeList;
|
||||
this.http = props.appstate.http;
|
||||
}
|
||||
|
||||
// componentWillUnmount(){
|
||||
|
||||
// }
|
||||
|
||||
async componentDidMount() {
|
||||
const {defaultValue={},mode} = this.props;
|
||||
await this.store.getList();
|
||||
}
|
||||
|
||||
|
||||
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],
|
||||
onNewRequest: (v) => {
|
||||
this.setState({
|
||||
formData: {
|
||||
...this.state.formData,
|
||||
[key]: v.id,
|
||||
}
|
||||
}, () => this.triggerOnChange(key));
|
||||
}
|
||||
});
|
||||
|
||||
const {mode="create"} = this.props;
|
||||
const dataSourceConfig = {
|
||||
text: 'name',
|
||||
value: 'id',
|
||||
};
|
||||
return(
|
||||
<div style={{marginTop: 10}}>
|
||||
<div className={"row"}>
|
||||
<div className={"col s12"}>
|
||||
<div>
|
||||
<p className="label-form">Item Name</p>
|
||||
{wrapperAutocomplete("user_store_id")(
|
||||
<AutoComplete
|
||||
hintText="E.g. Indah Kencana"
|
||||
dataSource={this.store.list.slice()}
|
||||
filter={AutoComplete.fuzzyFilter}
|
||||
dataSourceConfig={dataSourceConfig}
|
||||
openOnFocus={true}
|
||||
fullWidth={true}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
261
src/common/pages/FeaturedStores/Dialog/index.js
Normal file
261
src/common/pages/FeaturedStores/Dialog/index.js
Normal file
@@ -0,0 +1,261 @@
|
||||
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 FeaturedStoresData from './FeaturedStoresData';
|
||||
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 FeaturedStoresDialog extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
stepIndex: 0,
|
||||
formData: {},
|
||||
finished: false,
|
||||
openedDialog: false,
|
||||
formData: {},
|
||||
errorMessage: ''
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
this.customer = props.appstate.customer;
|
||||
this.featured = props.appstate.featured_store;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.setState({
|
||||
stepIndex: 0
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
onChangeForm(formData) {
|
||||
this.setState({formData});
|
||||
}
|
||||
|
||||
getStepContent(stepIndex) {
|
||||
|
||||
const {mode="create", defaultValue={}} = this.props;
|
||||
|
||||
switch (stepIndex) {
|
||||
case 0:
|
||||
return (
|
||||
<FeaturedStoresData
|
||||
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 = {
|
||||
user_store_id: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Please Select the Store'
|
||||
}
|
||||
],
|
||||
};
|
||||
|
||||
const validator = new schema(rules);
|
||||
|
||||
validator.validate(this.state.formData, (errs, f) => {
|
||||
console.log(errs);
|
||||
if (errs) {
|
||||
this.globalUI.showNotification("Something's Wrong", errs[0].message);
|
||||
} else {
|
||||
this.setState({
|
||||
stepIndex: stepIndex + 1,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
handlePrev = () => {
|
||||
const {stepIndex} = this.state;
|
||||
if (stepIndex > 0) {
|
||||
this.setState({stepIndex: stepIndex - 1});
|
||||
}
|
||||
};
|
||||
|
||||
closeDialog = ()=>{
|
||||
this.featured.formData.user_store_id = "";
|
||||
this.globalUI.hideDialog(DIALOG.FEATURED_STORES.CREATE)
|
||||
}
|
||||
|
||||
handleClose = () => {
|
||||
this.setState({confirmationDialog: false})
|
||||
};
|
||||
|
||||
save = () => {
|
||||
this.globalUI.hideDialog(DIALOG.FEATURED_STORES.CREATE);
|
||||
this.globalUI.showDialogLoading();
|
||||
const {mode="create", defaultValue={}} = this.props;
|
||||
|
||||
if (mode === "create") {
|
||||
let data = this.state.formData;
|
||||
this.featured.create(data)
|
||||
.then(res => {
|
||||
this.globalUI.hideDialogLoading();
|
||||
this.globalUI.openSnackbar("Success Added New Featured Class");
|
||||
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") {
|
||||
let data = this.state.formData;
|
||||
|
||||
this.featured.put(defaultValue.id, this.featured.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") ? "Choose" : "Update"} Store</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"}}>Store 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.FEATURED_STORES.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>
|
||||
)
|
||||
}
|
||||
}
|
||||
255
src/common/pages/FeaturedStores/index.js
Normal file
255
src/common/pages/FeaturedStores/index.js
Normal file
@@ -0,0 +1,255 @@
|
||||
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 ImageEdit from 'material-ui/svg-icons/image/edit';
|
||||
import EmptyComponent from '../EmptyComponent';
|
||||
import LoadingDialog from "../LoadingDialog";
|
||||
import Loader from 'react-loader-advanced';
|
||||
import {appConfig} from "../../config/app";
|
||||
import {Link} from 'react-router-dom';
|
||||
import {LINKS} from "../../routes";
|
||||
import moment from 'moment';
|
||||
import {DIALOG} from "../../stores/global_ui";
|
||||
import DialogCreate from './Dialog';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class FeaturedStoresComponent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
value: 0,
|
||||
edit : false,
|
||||
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.featured = props.appstate.featured_store;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.globalUI.openLoading();
|
||||
this.featured.getAll().then(res=>{
|
||||
this.globalUI.closeLoading();
|
||||
}).catch(err=>{
|
||||
this.globalUI.closeLoading();
|
||||
});
|
||||
}
|
||||
|
||||
handleUpdateInput = (searchText) => {
|
||||
this.setState({
|
||||
searchText: searchText,
|
||||
});
|
||||
};
|
||||
|
||||
handleNewRequest = () => {
|
||||
this.setState({
|
||||
searchText: '',
|
||||
});
|
||||
};
|
||||
|
||||
tabsHandleChange = (value) => {
|
||||
this.setState({
|
||||
slideIndex: value,
|
||||
});
|
||||
};
|
||||
|
||||
deleteClicked = (id) => {
|
||||
this.setState({
|
||||
id : id,
|
||||
openedDelete: true
|
||||
});
|
||||
}
|
||||
|
||||
editData = (index)=>{
|
||||
this.setState({
|
||||
edit : true,
|
||||
defaultValue : this.featured_store.data[index]
|
||||
},()=>{
|
||||
this.globalUI.showDialog(DIALOG.FEATURED_STORES.CREATE);
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
handleOpenDialog = () => {
|
||||
this.setState({
|
||||
edit : false
|
||||
})
|
||||
this.globalUI.showDialog(DIALOG.FEATURED_STORES.CREATE);
|
||||
}
|
||||
|
||||
handleClickDelete = (id) => {
|
||||
this.featured.delete(id).then(res=>{
|
||||
this.featured.getAll();
|
||||
this.setState({
|
||||
openedDelete: false,
|
||||
openSnackbarDelete: true
|
||||
});
|
||||
this.globalUI.openSnackbar("Successful Deleted Existing Featured Store");
|
||||
|
||||
}).catch(err=>{
|
||||
console.log(err);
|
||||
this.globalUI.openSnackbar(err.message);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
handleCloseDelete = () => {
|
||||
this.setState({
|
||||
openedDelete: false
|
||||
})
|
||||
}
|
||||
|
||||
handleChange = (event, index, value) => this.setState({value});
|
||||
|
||||
search = (event)=>{
|
||||
if(event.target.value.length == 0){
|
||||
this.featured.isSearching = false;
|
||||
}
|
||||
else{
|
||||
this.featured.isSearching = true;
|
||||
this.featured.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 Featured Store"
|
||||
style={{fontSize: 14}}
|
||||
hintStyle={{fontSize: 14}}
|
||||
underlineShow={false}
|
||||
onChange={this.search}
|
||||
/>
|
||||
</ToolbarGroup>
|
||||
<ToolbarGroup className="ToolbarGroupLast">
|
||||
<ToolbarSeparator/>
|
||||
<RaisedButton className="ToolbarGroupLastButton" icon={<AddIcon/>} label="New Store"
|
||||
primary={true} onClick={this.handleOpenDialog}/>
|
||||
</ToolbarGroup>
|
||||
</Toolbar>
|
||||
<Divider/>
|
||||
<div style={{paddingBottom: 5}}>
|
||||
<Loader show={this.globalUI.loadingVisibility} message={<LoadingDialog/>}
|
||||
messageStyle={{textAlign: 'center'}} backgroundStyle={{backgroundColor: 'rgba(255,255,255,0.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', textAlign: 'right'}}>Action</TableHeaderColumn>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody displayRowCheckbox={false}>
|
||||
{(!this.featured.isEmpty) ? (this.featured.isSearching ? this.featured.dataFiltered : this.featured.data).map((item, index) => {
|
||||
return (
|
||||
<TableRow key={item.id}>
|
||||
<TableRowColumn>
|
||||
<div style={{color : '#6772e5',cursor : 'pointer'}} onClick={()=>this.handleOpenEdit(item.id)}>
|
||||
{item.name}
|
||||
</div>
|
||||
</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>
|
||||
</Loader>
|
||||
</div>
|
||||
<Dialog
|
||||
title="Warning"
|
||||
actions={actionsDelete}
|
||||
modal={true}
|
||||
open={this.state.openedDelete}
|
||||
onRequestClose={() => this.handleCloseDelete()}
|
||||
>
|
||||
Are you sure want to delete this data?
|
||||
</Dialog>
|
||||
{this.state.edit ? <DialogCreate mode="update" defaultValue={Object.assign({},this.state.defaultValue)}/> : <DialogCreate mode="create"/>}
|
||||
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
}
|
||||
108
src/common/pages/ForgotPassword/Form.js
Normal file
108
src/common/pages/ForgotPassword/Form.js
Normal file
@@ -0,0 +1,108 @@
|
||||
import React from "react";
|
||||
import {Button, Form, Input, Select} from "antd";
|
||||
const {Option, OptGroup} = Select;
|
||||
const FormItem = Form.Item;
|
||||
|
||||
class ComponentName extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
pass_min_length: 4
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
}
|
||||
|
||||
submit(e) {
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
this
|
||||
.props
|
||||
.form
|
||||
.validateFields((err, value) => {
|
||||
if (err) {
|
||||
return console.error(err);
|
||||
}
|
||||
|
||||
if (this.props.onSubmit && this.props.onSubmit instanceof Function) {
|
||||
this
|
||||
.props
|
||||
.onSubmit(this.props.form, Object.assign({}, value));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onCancel() {
|
||||
// todo, find better way to check if onCancel is a function
|
||||
if (this.props.onCancel && this.props.onCancel instanceof Function) {
|
||||
this
|
||||
.props
|
||||
.onCancel(this.props.form);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const {getFieldDecorator} = this.props.form;
|
||||
|
||||
const emailRule = getFieldDecorator('username', {
|
||||
rules: [
|
||||
{
|
||||
type: 'email',
|
||||
message: 'Email format not valid'
|
||||
}, {
|
||||
required: true,
|
||||
message: 'Please input your email'
|
||||
}
|
||||
],
|
||||
initialValue: this.props.username
|
||||
});
|
||||
|
||||
const passwordRule = getFieldDecorator('password', {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Please input your password'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
return (
|
||||
<Form>
|
||||
<FormItem>
|
||||
{emailRule(
|
||||
<Input className="box-input"
|
||||
placeholder="Email"/>
|
||||
)}
|
||||
</FormItem>
|
||||
|
||||
<FormItem>
|
||||
{passwordRule(
|
||||
<Input className="box-input'"
|
||||
type="password"
|
||||
placeholder="Password"/>
|
||||
)}
|
||||
</FormItem>
|
||||
|
||||
<Button
|
||||
style={{
|
||||
width: "100%",
|
||||
marginBottom: 10
|
||||
}}
|
||||
type="primary"
|
||||
size="large"
|
||||
onClick={() => this.submit()}>
|
||||
Sign in
|
||||
</Button>
|
||||
<p>{this.props.footer}</p>
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default Form.create()(ComponentName);
|
||||
211
src/common/pages/ForgotPassword/index.js
Normal file
211
src/common/pages/ForgotPassword/index.js
Normal file
@@ -0,0 +1,211 @@
|
||||
import React from 'react';
|
||||
import {Card, CardActions, CardText, CardTitle, Divider, Paper, RaisedButton, TextField,Dialog,FlatButton} from 'material-ui';
|
||||
import {inject, observer} from 'mobx-react';
|
||||
|
||||
import './style.scss'
|
||||
import {LINKS} from "../../routes";
|
||||
import {getMobileOperatingSystem} from '../../stores/firebase';
|
||||
import {Helmet} from "react-helmet";
|
||||
import LoadingDialog from '../LoadingDialog/index';
|
||||
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class ForgotPasswordComponent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
email: "",
|
||||
password: "",
|
||||
open : false,
|
||||
message : 'HAI',
|
||||
status : 0,
|
||||
loading : false
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.authStore = props.appstate.auth;
|
||||
this.http = props.appstate.http;
|
||||
this.settingStore = props.appstate.setting;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.settingStore.getAll();
|
||||
}
|
||||
|
||||
handleTextFieldChange = (event, name) => {
|
||||
console.log(event.target.value);
|
||||
this.setState({
|
||||
[name]: event.target.value
|
||||
});
|
||||
};
|
||||
|
||||
forgotPassword() {
|
||||
this.setState({
|
||||
loading : true
|
||||
});
|
||||
this.authStore.forgetPassword({email : this.state.email})
|
||||
.then(res=>{
|
||||
this.setState({
|
||||
loading : false,
|
||||
open : true,
|
||||
message : 'Succeed forgot password, please check your email',
|
||||
status : 1
|
||||
})
|
||||
}).catch(err=>{
|
||||
this.setState({
|
||||
loading : false,
|
||||
open : true,
|
||||
message : 'User with that email not found',
|
||||
status : 0
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
closeDialog = ()=>{
|
||||
if(this.state.status){
|
||||
this.props.history.push(LINKS.LOGIN);
|
||||
}
|
||||
else{
|
||||
this.setState({
|
||||
open : false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const actions1 = [
|
||||
<FlatButton
|
||||
label="Ok"
|
||||
primary={true}
|
||||
onClick={()=>this.closeDialog()}
|
||||
style={{marginRight: 10}}
|
||||
/>
|
||||
];
|
||||
|
||||
// const applicationIcon = (this.settingStore.isIconEmpty) ? "/assets/images/logo_ikan.png" : this.http.appendImagePath(this.settingStore.setting.icon);
|
||||
const applicationIcon = "/assets/images/logo_ikan.png";
|
||||
return (
|
||||
<div className="login">
|
||||
<Helmet>
|
||||
<meta charSet="utf-8"/>
|
||||
<title>Forgot Passwords</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<link rel="icon" type="image/png" href={applicationIcon} sizes="96x96"/>
|
||||
</Helmet>
|
||||
<div style={{width: "100%"}}>
|
||||
{/*
|
||||
(this.settingStore.isIconEmpty) ?
|
||||
<div style={{textAlign: "center"}}>
|
||||
<Paper style={{
|
||||
backgroundSize: "contain",
|
||||
backgroundClip: "padding-box",
|
||||
padding: 10,
|
||||
height: 75, width: 75,
|
||||
background: '#fff',
|
||||
marginRight: "auto",
|
||||
marginLeft: "auto"
|
||||
}} zDepth={1} circle={true}>
|
||||
<img className="logo" src="/assets/images/logo_ikan.png"/>
|
||||
</Paper>
|
||||
<h2 style={{
|
||||
color: '#275164',
|
||||
marginRight: "auto",
|
||||
marginLeft: "auto",
|
||||
maxWidth: 500,
|
||||
marginTop: 15,
|
||||
marginBottom: 0
|
||||
}}>5 Roti dan 2 Ikan</h2>
|
||||
</div>
|
||||
:
|
||||
<div style={{textAlign: "center"}}>
|
||||
<Paper style={{
|
||||
backgroundSize: "contain",
|
||||
backgroundClip: "padding-box",
|
||||
padding: 10,
|
||||
height: 75, width: 75,
|
||||
background: '#fff',
|
||||
marginRight: "auto",
|
||||
marginLeft: "auto"
|
||||
}} zDepth={1} circle={true}>
|
||||
<img className="logo"
|
||||
src={this.http.appendImagePath(this.settingStore.setting.icon)}/>
|
||||
</Paper>
|
||||
<h2 style={{
|
||||
color: '#275164',
|
||||
marginRight: "auto",
|
||||
marginLeft: "auto",
|
||||
maxWidth: 500,
|
||||
marginTop: 15,
|
||||
marginBottom: 0
|
||||
}}>{this.settingStore.setting.name}</h2>
|
||||
</div>
|
||||
*/}
|
||||
<div style={{textAlign: "center"}}>
|
||||
<Paper style={{
|
||||
backgroundSize: "contain",
|
||||
backgroundClip: "padding-box",
|
||||
padding: 10,
|
||||
height: 75, width: 75,
|
||||
background: '#fff',
|
||||
marginRight: "auto",
|
||||
marginLeft: "auto"
|
||||
}} zDepth={1} circle={true}>
|
||||
<img className="logo" src={applicationIcon}/>
|
||||
</Paper>
|
||||
<h2 style={{
|
||||
color: '#275164',
|
||||
marginRight: "auto",
|
||||
marginLeft: "auto",
|
||||
maxWidth: 500,
|
||||
marginTop: 15,
|
||||
marginBottom: 0
|
||||
}}>Marketplace</h2>
|
||||
</div>
|
||||
</div>
|
||||
<Card style={{width: 350, marginTop: '18px'}} className="cardLite align-center">
|
||||
<CardTitle title={<p style={{fontSize: 14}}>Forgot Password</p>}>
|
||||
<Divider style={{backgroundColor: '#48d8b2', width: '150px'}} className="margin-auto"/>
|
||||
</CardTitle>
|
||||
<form>
|
||||
<CardText>
|
||||
<TextField
|
||||
hintText="Email"
|
||||
fullWidth={true}
|
||||
name="email"
|
||||
type="text"
|
||||
value={this.state.email}
|
||||
onChange={(event) => this.handleTextFieldChange(event, 'email')}
|
||||
/>
|
||||
</CardText>
|
||||
<CardActions>
|
||||
<RaisedButton primary={true} label="Send New Password Link" onClick={this.forgotPassword.bind(this)}/>
|
||||
</CardActions>
|
||||
</form>
|
||||
<a style={{fontSize: 12, fontWeight: 500, display: 'block', margin: '18px 0px 30px'}}
|
||||
onClick={() => this.props.history.push(LINKS.LOGIN)}>Back to Login</a>
|
||||
</Card>
|
||||
|
||||
<Dialog
|
||||
open={this.state.open}
|
||||
contentStyle={{maxWidth: 350}}
|
||||
onRequestClose={()=>this.setState({open:false})}
|
||||
actions={actions1}
|
||||
modal={true}
|
||||
>
|
||||
{this.state.message}
|
||||
</Dialog>
|
||||
|
||||
<Dialog
|
||||
open={this.state.loading}
|
||||
contentStyle={{maxWidth: 350}}
|
||||
modal={true}
|
||||
>
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<LoadingDialog/>
|
||||
</div>
|
||||
</Dialog>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
61
src/common/pages/ForgotPassword/style.scss
Normal file
61
src/common/pages/ForgotPassword/style.scss
Normal file
@@ -0,0 +1,61 @@
|
||||
.login {
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
//background-size: cover;
|
||||
//position: fixed;
|
||||
//height: 100%;
|
||||
//width: 100%;
|
||||
//top:0;
|
||||
//overflow: hidden;
|
||||
.logo {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.background {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background: rgba(128, 0, 128, 0.82); /* fallback for old browsers */
|
||||
background: -webkit-linear-gradient(to top, rgba(0, 204, 187, 0.86), rgba(43, 69, 230, 0.91), rgba(128, 0, 128, 0.92)); /* Chrome 10-25, Safari 5.1-6 */
|
||||
background: linear-gradient(to top, rgba(0, 204, 187, 0.86), rgba(43, 69, 230, 0.91), rgba(128, 0, 128, 0.92));
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
.ant-form-explain {
|
||||
text-align: left;
|
||||
}
|
||||
.login-box {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 460px;
|
||||
height: 320px;
|
||||
padding: 36px;
|
||||
height: 100vh;
|
||||
background-color: #1e2e4a;
|
||||
box-shadow: 0 0 100px rgba(0, 0, 0, .08);
|
||||
.header {
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
margin-bottom: 24px;
|
||||
img {
|
||||
width: 40px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
span {
|
||||
vertical-align: text-bottom;
|
||||
font-size: 16px;
|
||||
text-transform: uppercase;
|
||||
display: inline-block;
|
||||
}
|
||||
p {
|
||||
font-size: 16px;
|
||||
text-transform: uppercase;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
703
src/common/pages/Help/FormHelp/index.js
Normal file
703
src/common/pages/Help/FormHelp/index.js
Normal file
@@ -0,0 +1,703 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import {
|
||||
Card,
|
||||
FlatButton,
|
||||
Divider,
|
||||
RaisedButton,
|
||||
Toolbar,
|
||||
MenuItem,
|
||||
ToolbarGroup,
|
||||
IconButton,
|
||||
ToolbarTitle,
|
||||
Dialog,
|
||||
Toggle
|
||||
} from 'material-ui';
|
||||
import SaveIcon from 'material-ui/svg-icons/content/save';
|
||||
import PublishIcon from 'material-ui/svg-icons/editor/publish';
|
||||
import DeleteIcon from 'material-ui/svg-icons/action/delete';
|
||||
import AddIcon from 'material-ui/svg-icons/content/add';
|
||||
import { Upload, Icon, Modal, Input, Select, Switch, message, Button as ButtonAntd, Affix} from 'antd'
|
||||
import {LINKS} from "../../../routes";
|
||||
import uuid from 'uuid';
|
||||
//import {appConfig} from "../../../config/app";
|
||||
import NumberFormat from 'react-number-format';
|
||||
//import {DIALOG} from "../../../stores/global_ui";
|
||||
//import ClassDetail from '../index.js';
|
||||
import DC from 'decimal.js-light';
|
||||
import { action } from 'mobx/lib/mobx';
|
||||
const InputGroup = Input.Group;
|
||||
const { TextArea } = Input;
|
||||
const Option = Select.Option;
|
||||
// import AttachmentIcon from 'material-ui/svg-icons/file/attachment';
|
||||
// import Avatar from 'material-ui/Avatar';
|
||||
// import Chip from 'material-ui/Chip';
|
||||
|
||||
// Require Editor JS files.
|
||||
import 'froala-editor/js/froala_editor.pkgd.min.js';
|
||||
|
||||
// Require Editor CSS files.
|
||||
import 'froala-editor/css/froala_style.min.css';
|
||||
import 'froala-editor/css/froala_editor.pkgd.min.css';
|
||||
|
||||
// Require Font Awesome.
|
||||
import 'font-awesome/css/font-awesome.css';
|
||||
|
||||
import FroalaEditor from 'react-froala-wysiwyg';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class FormHelp extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.rewardStore = props.appstate.reward;
|
||||
this.state = {
|
||||
openedDialogEmpty:false,
|
||||
featured_media_exist: false,
|
||||
text: '',
|
||||
openedDialog: false,
|
||||
openDeleteDialog : false,
|
||||
saveButton: true,
|
||||
value: 1,
|
||||
isFree : false,
|
||||
searchText: '',
|
||||
slideIndex: 0,
|
||||
openedDialogBack: false,
|
||||
reward_type: "Choose Reward Type",
|
||||
expanded: false,
|
||||
previewVisible: false,
|
||||
previewImage: '',
|
||||
fileList: [],
|
||||
fileLength: 0,
|
||||
fileMainExist: false,
|
||||
formData: {
|
||||
tags: ['a571f41f-c9d2-4fe1-9638-320c589cffe3'],
|
||||
// custom_fields: [],
|
||||
// is_free : false
|
||||
},
|
||||
disabled_price : false,
|
||||
mode: 'create',
|
||||
html : "",
|
||||
config: {
|
||||
placeholderText: 'Edit Your Content Here!',
|
||||
charCounterCount: true,
|
||||
toolbarStickyOffset: 73,
|
||||
toolbarButtons: ['insertLink', 'bold', 'italic', 'underline', 'fontFamily', 'fontSize', 'color', 'align', 'formatOL', 'formatUL', 'embedly', '|', 'insertImage', 'insertVideo', 'insertFile', '|', 'help'],
|
||||
quickInsertButtons: ['embedly','hr', 'image', 'video'],
|
||||
codeBeautifierOptions: {
|
||||
end_with_newline: true,
|
||||
indent_inner_html: true,
|
||||
extra_liners: "['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'pre', 'ul', 'ol', 'table', 'dl']",
|
||||
brace_style: 'expand',
|
||||
indent_char: ' ',
|
||||
indent_size: 4,
|
||||
wrap_line_length: 0
|
||||
},
|
||||
heightMin: '50vh'
|
||||
}
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.http = props.appstate.http;
|
||||
this.authStore = props.appstate.auth;
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
this.categoryStore = props.appstate.category;
|
||||
this.itemStore = props.appstate.item;
|
||||
this.myStoreItem = props.appstate.myStoreItem;
|
||||
//this.classStore = props.appstate.class;
|
||||
this.helpStore = props.appstate.help;
|
||||
this.editor = null;
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
console.log(this.props.match.params.id,'ini id params')
|
||||
window.scrollTo(0, 0);
|
||||
// await this.helpStore.getClassItem(this.props.match.params.id);
|
||||
// await this.helpStore.getClassDetail(this.props.match.params.id)
|
||||
// await this.helpStore.getClassItem();
|
||||
|
||||
if(this.props.match.params.id){
|
||||
this.helpStore.getDetail(this.props.match.params.id).then(res => {
|
||||
console.log(this.helpStore.selected.title,this.helpStore.selected.content,'res detail')
|
||||
|
||||
this.setState({
|
||||
formData : {
|
||||
title:this.helpStore.selected.title,
|
||||
content:this.helpStore.selected.content,
|
||||
},
|
||||
text : this.helpStore.selected.content,
|
||||
});
|
||||
console.log("new formmm",this.state.formData,this.state.text,this.state.title)
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
// this.setState({
|
||||
// formData : {
|
||||
// title:this.helpStore.selected.title,
|
||||
// content:this.helpStore.selected.content,
|
||||
// },
|
||||
// text : this.helpStore.selected.content,
|
||||
// });
|
||||
// console.log("new formmm",this.state.formData,this.state.text,this.state.title)
|
||||
}
|
||||
else{
|
||||
console.log('ini else');
|
||||
}
|
||||
|
||||
// $('.fr-wrapper').children[0].style.display = 'none';
|
||||
// setTimeout(() => {
|
||||
// $('.fr-wrapper').children[0].style.display = 'none';
|
||||
// }, 1000);
|
||||
}
|
||||
|
||||
handleModelChange = (model) => {
|
||||
this.setState({
|
||||
text: model
|
||||
});
|
||||
};
|
||||
|
||||
handleCancel = () => this.setState({ previewVisible: false });
|
||||
|
||||
|
||||
handleOpen = () => {
|
||||
console.log(this.state.html,'heree');
|
||||
this.setState({openedDialog: true});
|
||||
};
|
||||
|
||||
handleClose = () => {
|
||||
this.setState({openedDialog: false});
|
||||
};
|
||||
|
||||
goToClassDetail(){
|
||||
this.props.history.push(`${LINKS.CLASSES}/${this.props.match.params.id}`);
|
||||
}
|
||||
|
||||
postData = () => {
|
||||
console.log("post!!!", this.state.formData);
|
||||
if(!this.state.formData.title || this.state.formData.title=="" || !this.state.text || this.state.text==""){
|
||||
message.success('Title and content cannot be empty!');
|
||||
console.log('inikosongdatanya')
|
||||
this.setState({openedDialog: false});
|
||||
this.setState({openedDialogEmpty:true});
|
||||
}
|
||||
else{
|
||||
this.setState({openedDialog: false});
|
||||
this.globalUI.openLoading();
|
||||
const data=Object.assign({},this.state.formData);
|
||||
data.content=this.state.text;
|
||||
// if(typeof data.price === "string"){
|
||||
// data.price = new DC(data.price.replace(/\,/g,"")).toFixed();
|
||||
// }
|
||||
|
||||
console.log("data",data);
|
||||
this.helpStore.post(data)
|
||||
.then(res => {
|
||||
this.globalUI.hideDialogLoading();
|
||||
this.globalUI.openSnackbar("Success Added New Help");
|
||||
this.props.history.push(LINKS.HELP);
|
||||
})
|
||||
.catch(err => {
|
||||
this.globalUI.openSnackbar(err.message);
|
||||
console.error(err, 'ini errornya');
|
||||
|
||||
});
|
||||
// this.helpStore.postClassItem(this.props.match.params.id,data).then(async()=>{
|
||||
// await message.success('Success Added New Course');
|
||||
// await this.globalUI.closeLoading();
|
||||
// await this.helpStore.getAll();
|
||||
// this.goToClassDetail();
|
||||
// })
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
deleteData = () => {
|
||||
|
||||
};
|
||||
|
||||
editData = () => {
|
||||
console.log("Edit!!!", this.state.formData);
|
||||
if(!this.state.formData.title || this.state.formData.title=="" || !this.state.text || this.state.text==""){
|
||||
console.log('inikosongdatanya')
|
||||
this.setState({openedDialog: false});
|
||||
this.setState({openedDialogEmpty:true});
|
||||
}
|
||||
else{
|
||||
this.globalUI.openLoading();
|
||||
this.setState({openedDialog: false});
|
||||
const data=Object.assign({},this.state.formData);
|
||||
data.content=this.state.text;
|
||||
console.log("data",data);
|
||||
// if(typeof data.price == "string"){
|
||||
// data.price = new DC(data.price.replace(/\,/g,"")).toFixed();
|
||||
// }
|
||||
console.log("data",data);
|
||||
this.helpStore.put(this.props.match.params.id,data)
|
||||
.then(res => {
|
||||
this.globalUI.hideDialogLoading();
|
||||
this.globalUI.openSnackbar("Success Edit Help");
|
||||
this.props.history.push(LINKS.HELP);
|
||||
})
|
||||
.catch(err => {
|
||||
this.globalUI.openSnackbar(err.message);
|
||||
console.error(err, 'ini errornya');
|
||||
|
||||
});
|
||||
// this.helpStore.putClassItem(this.props.match.params.id_course,data).then(async()=>{
|
||||
// await message.success('Success Edit New Course');
|
||||
// await this.globalUI.closeLoading();
|
||||
// await this.helpStore.getAll();
|
||||
// this.goToClassDetail();
|
||||
// })
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
handleBackClose = () => {
|
||||
this.setState({openedDialogBack: false})
|
||||
};
|
||||
|
||||
handleEmptyClose = () => {
|
||||
this.setState({openedDialogEmpty: false})
|
||||
};
|
||||
|
||||
handleEmptyOpen = () => {
|
||||
this.setState({openedDialogEmpty: true})
|
||||
};
|
||||
|
||||
handleBackOpen = () => {
|
||||
this.setState({openedDialogBack: true});
|
||||
};
|
||||
|
||||
inputContent = (evt)=>{
|
||||
// console.log(evt.target.value);
|
||||
this.setState({
|
||||
html : evt.target.value
|
||||
})
|
||||
}
|
||||
|
||||
handleChange = ({ fileList }) => {this.setState({ fileList }); console.log(fileList, 'remove')};
|
||||
|
||||
uploaderHandler({file, onProgress}) {
|
||||
console.log(file, 'upload');
|
||||
console.log("fileLength", this.state.fileLength);
|
||||
console.log("fileMainExist", this.state.fileMainExist);
|
||||
this.http.upload(file)
|
||||
.then(res => {
|
||||
const {fileList} = this.state;
|
||||
let newFileList = fileList.filter((obj)=>{
|
||||
if(!obj.lastModified){
|
||||
return true;
|
||||
}
|
||||
|
||||
})
|
||||
if(!this.state.fileMainExist){
|
||||
newFileList.push({
|
||||
uid: newFileList.length,
|
||||
name: file.name,
|
||||
status: 'done',
|
||||
url: this.http.appendImagePath(res.path),
|
||||
path: res.path,
|
||||
type: 'main'
|
||||
});
|
||||
}
|
||||
else{
|
||||
newFileList.push({
|
||||
uid: newFileList.length,
|
||||
name: file.name,
|
||||
status: 'done',
|
||||
url: this.http.appendImagePath(res.path),
|
||||
path: res.path,
|
||||
type: 'gallery'
|
||||
});
|
||||
}
|
||||
|
||||
console.log("update fileList",fileList);
|
||||
console.log("new fileList",newFileList);
|
||||
this.setState({fileList : newFileList});
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
handleWarningDialog = (bool)=>{
|
||||
this.setState({
|
||||
openDeleteDialog : bool
|
||||
})
|
||||
}
|
||||
|
||||
setFree = (bool) =>{
|
||||
this.setState({
|
||||
formData : {
|
||||
...this.state.formData,
|
||||
is_free: bool,
|
||||
price : 0
|
||||
},
|
||||
disabled_price : bool
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
//add mock data for tag option, change this if api for tag is complete
|
||||
const children = [];
|
||||
for (let i = 10; i < 36; i++) {
|
||||
children.push(<Option key={i.toString(36) + i}>{i.toString(36) + i}</Option>);
|
||||
}
|
||||
|
||||
const { previewVisible, previewImage, fileList } = this.state;
|
||||
|
||||
const uploadButton = (
|
||||
<div>
|
||||
<Icon type="plus" />
|
||||
<div className="ant-upload-text">Upload</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const actions = [
|
||||
<FlatButton
|
||||
label="Cancel"
|
||||
primary={true}
|
||||
style={{marginRight: 10}}
|
||||
onClick={this.handleClose}
|
||||
/>,
|
||||
<RaisedButton
|
||||
label={this.props.match.params.id ? "Edit" : "Publish"}
|
||||
primary={true}
|
||||
disabled={this.itemStore.isLoading}
|
||||
onClick={this.props.match.params.id ? this.editData : this.postData}
|
||||
/>,
|
||||
];
|
||||
|
||||
const actionsDelete = [
|
||||
<FlatButton
|
||||
label="Cancel"
|
||||
primary={true}
|
||||
style={{marginRight: 10}}
|
||||
onClick={()=>this.handleWarningDialog(false)}
|
||||
/>,
|
||||
<RaisedButton
|
||||
label={"Delete"}
|
||||
primary={true}
|
||||
disabled={this.itemStore.isLoading}
|
||||
onClick={this.deleteData}
|
||||
/>,
|
||||
];
|
||||
|
||||
const actionsBack = [
|
||||
<FlatButton
|
||||
label="No"
|
||||
primary={true}
|
||||
style={{marginRight: 10}}
|
||||
onClick={this.handleBackClose}
|
||||
/>,
|
||||
<RaisedButton
|
||||
label="Yes"
|
||||
primary={true}
|
||||
onClick={() => this.props.history.goBack()}
|
||||
/>,
|
||||
];
|
||||
|
||||
const actionsEmpty = [
|
||||
<RaisedButton
|
||||
label="Yes"
|
||||
primary={true}
|
||||
onClick={this.handleEmptyClose}
|
||||
/>,
|
||||
];
|
||||
|
||||
const wrapperText = key => ele => React.cloneElement(ele, {
|
||||
value: this.state.formData[key],
|
||||
onChange: (e) => {
|
||||
let data = e.target.value
|
||||
this.setState({
|
||||
formData: {
|
||||
...this.state.formData,
|
||||
[key]: data
|
||||
}
|
||||
});
|
||||
// if(!this.state.formData.title || !this.state.text){
|
||||
// this.setState({saveButton:true});
|
||||
// }
|
||||
// else{
|
||||
// this.setState({saveButton:false});
|
||||
// }
|
||||
console.log("value",this.state.formData[key]);
|
||||
console.log("value2",e.target.value);
|
||||
console.log("key",key);
|
||||
}
|
||||
});
|
||||
|
||||
// const wrapperSelect = key => ele => React.cloneElement(ele, {
|
||||
// value: this.state.formData[key],
|
||||
// onChange: (e, k, v) => {
|
||||
// this.setState({
|
||||
// formData: {
|
||||
// ...this.state.formData,
|
||||
// [key]: e,
|
||||
// }
|
||||
// }, () => this.triggerOnChange());
|
||||
// }
|
||||
// });
|
||||
|
||||
// const editorOptions = {
|
||||
// commands: [
|
||||
// {
|
||||
// command: 'bold',
|
||||
// key: 'b',
|
||||
// meta: true,
|
||||
// shift: false
|
||||
// },
|
||||
// {
|
||||
// command: 'italic',
|
||||
// key: 'i',
|
||||
// meta: true,
|
||||
// shift: false
|
||||
// },
|
||||
// {
|
||||
// command: 'underline',
|
||||
// key: 'u',
|
||||
// meta: true,
|
||||
// shift: false
|
||||
// }
|
||||
// ],
|
||||
// toolbar: {
|
||||
// buttons: ['h1','h2','h3','bold', 'italic', 'underline', 'image', 'video','anchor']
|
||||
// },
|
||||
// extensions:{
|
||||
// 'video': new MediumButton({
|
||||
// label:'<b>Video</b>',
|
||||
// tagNames:['video'],
|
||||
// // start:'<video width="100%" heigth="100%" controls="true" src="',
|
||||
// // end:'" />',
|
||||
// action: (markedWord,isMarked,parent)=>{
|
||||
// console.log("markedWord",markedWord);
|
||||
// console.log("isMarked",isMarked);
|
||||
// console.log("parent",parent);
|
||||
// // return markedWord;
|
||||
// if(markedWord.includes(("youtube"||"facebook"))){
|
||||
// return '<iframe width="90%" heigth="100%" controls="true" src="'+markedWord+'" style="vertical-align:middle" />';
|
||||
// }
|
||||
// else{
|
||||
// return '<video width="90%" heigth="100%" controls="true" src="'+markedWord+'" style="vertical-align:middle" />';
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
return (
|
||||
|
||||
<div style={{marginTop: 35}}>
|
||||
<div className="row">
|
||||
<div className="col s12">
|
||||
<Card className="animated fadeIn cardLite" style={{marginLeft: 12, marginRight: 12}}>
|
||||
<Toolbar className="toolbarCard" style={{backgroundColor: '#fff'}}>
|
||||
<ToolbarGroup>
|
||||
<IconButton
|
||||
iconClassName="material-icons"
|
||||
tooltip="Back"
|
||||
style={{marginLeft: '-10px'}}
|
||||
onClick={this.handleBackOpen}
|
||||
>
|
||||
arrow_back
|
||||
</IconButton>
|
||||
<ToolbarTitle style={{fontSize: 14, fontWeight: 500, color: '#32325d'}} text={this.props.match.params.id ? 'Edit Help' : 'Create Help'}/>
|
||||
</ToolbarGroup>
|
||||
<ToolbarGroup>
|
||||
{/*<Button>Submit</Button>*/}
|
||||
{!(this.state.mode == 'create') ? <RaisedButton onClick={()=>this.handleWarningDialog(true)} icon={<DeleteIcon/>} label="Delete" primary={true} style={{marginRight : '1px'}}/> : ''}
|
||||
{/*!(this.state.mode == 'update') ? <RaisedButton icon={<SaveIcon/>} label="Save as draft" primary={true} style={{marginRight : '1px'}}/> : ''*/}
|
||||
</ToolbarGroup>
|
||||
</Toolbar>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
<div className={"row"}>
|
||||
<div className={"col s12"}>
|
||||
<div className="row">
|
||||
<div className={"col s9"}>
|
||||
<Card className="animated fadeIn cardLite">
|
||||
<FroalaEditor
|
||||
model={this.state.text}
|
||||
config={this.state.config}
|
||||
onModelChange={this.handleModelChange}
|
||||
onManualControllerReady={(initControls) => {
|
||||
console.log(initControls, 'initControls initControls');
|
||||
initControls.initialize();
|
||||
this.editor = initControls.getEditor();
|
||||
this.editor().on('froalaEditor.image.beforeUpload', (e, editor, files) => {
|
||||
if (files.length) {
|
||||
let name = files[0].name;
|
||||
this.props.appstate.http.upload(files[0]).then(it => {
|
||||
editor.image.insert(this.http.appendImagePath(it.path), name, null, editor.image.get());
|
||||
// console.log(it);
|
||||
});
|
||||
// let reader = new FileReader();
|
||||
// reader.onload = (e) => {
|
||||
// let result = e.target.result;
|
||||
// editor.image.insert(result, null, null, editor.image.get());
|
||||
// };
|
||||
// reader.readAsDataURL(files[0]);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
this.editor().on('froalaEditor.file.beforeUpload', (e, editor, files) => {
|
||||
// console.log(e, editor, files, 'blah blah blah')
|
||||
if (files.length) {
|
||||
let name = files[0].name;
|
||||
this.props.appstate.http.upload(files[0]).then(it => {
|
||||
editor.file.insert(this.http.appendImagePath(it.path), name, null);
|
||||
// console.log(it);
|
||||
});
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
this.editor().on('froalaEditor.video.beforeUpload', (e, editor, files) => {
|
||||
// console.log(e, editor, files, 'blah blah blah')
|
||||
if (files.length) {
|
||||
let name = files[0].name;
|
||||
// console.log(editor.video);
|
||||
this.props.appstate.http.upload(files[0]).then(it => {
|
||||
this.editor('video.insert', `<iframe controls="true" width="90%" height="100%" src="${this.http.appendImagePath(it.path)}" style="vertical-align:middle"/>`, false);
|
||||
// console.log(it);
|
||||
});
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Card>
|
||||
</div>
|
||||
<div className={"col s3"}>
|
||||
<Affix offsetTop={85}>
|
||||
<Card className="animated fadeIn cardLite">
|
||||
<div style={{padding: '14px'}}>
|
||||
<div className="row">
|
||||
<p className="label-form">Title Help</p>
|
||||
{wrapperText("title")(
|
||||
<Input placeholder="E.g. Cara Membeli Item" autosize type={"text"}/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{this.props.match.params.id ? (<ButtonAntd type={'primary'} style={{width: '100%', marginTop: 25}} onClick={this.handleOpen} icon={'upload'}>Edit</ButtonAntd>) : (<ButtonAntd type={'primary'} style={{width: '100%', marginTop: 25}} onClick={this.handleOpen} icon={'upload'}>Publish</ButtonAntd>)}
|
||||
|
||||
{/* <div style={{display: 'flex', flexDirection: 'row', justifyContent: 'space-between'}}>
|
||||
<span className="label-form" style={{marginTop: 5}}>Free Course?</span>
|
||||
<Switch checkedChildren={<Icon type="check" />} unCheckedChildren={<Icon style={{color: '#fff'}} type="cross" />} onChange={this.setFree} checked={this.state.disabled_price}/>
|
||||
</div> */}
|
||||
{/* {
|
||||
this.helpStore.classData.type === 'pay_per_course' ?
|
||||
<div className="row" style={{marginTop: 27}}>
|
||||
<p className="label-form">Price</p>
|
||||
{wrapperText("price")(
|
||||
<NumberFormat disabled={this.state.disabled_price} thousandSeparator={true} style={{ width: '100%', padding: '4px 11px', height: '32px', fontSize: '14px', border: '1px solid #d9d9d9', borderRadius: '4px' }} placeholder="E.g. 50" />
|
||||
)}
|
||||
</div>
|
||||
: <div></div>
|
||||
} */}
|
||||
{/*<RaisedButton onClick={() => {*/}
|
||||
{/*this.props.appstate.files.onFileSelected = (path,mime_type) => {*/}
|
||||
{/*console.log("this.props.appstate.files.onFileSelected",this.props.appstate.files.lastFile);*/}
|
||||
{/*let file = this.props.appstate.files.lastFile;*/}
|
||||
{/*if(!this.state.featured_media_exist && file.mime_type.includes("image")){*/}
|
||||
{/*this.setState({formData:{...this.state.formData, featured_media:path,featured_media_type:file.mime_type}});*/}
|
||||
{/*this.setState({featured_media_exist:true});*/}
|
||||
{/*console.log("featuredExistNow");*/}
|
||||
{/*}*/}
|
||||
{/*// this.mediumEditorInstance.restoreSelection();*/}
|
||||
{/*if(file.mime_type.includes("image")){*/}
|
||||
{/*this.editor('image.insert', this.http.appendImagePath(path), true);*/}
|
||||
{/*// this.mediumEditorInstance.pasteHTML(*/}
|
||||
{/*// `<img src="${this.http.appendImagePath(path)}" style="margin: 0 auto;">`,*/}
|
||||
{/*// {cleanAttrs: []});*/}
|
||||
{/*}*/}
|
||||
{/*else if(file.mime_type.includes("video")){*/}
|
||||
{/*this.editor('html.insert', `<video controls="true" width="90%" height="100%" src="${this.http.appendImagePath(path)}" style="vertical-align:middle"/>`, false);*/}
|
||||
{/*// this.mediumEditorInstance.pasteHTML(*/}
|
||||
{/*// `<video controls="true" width="90%" height="100%" src="${this.http.appendImagePath(path)}" style="vertical-align:middle"/>`,*/}
|
||||
{/*// {cleanAttrs: []});*/}
|
||||
{/*}*/}
|
||||
{/*else if(file.mime_type.includes("audio")){*/}
|
||||
{/*this.editor('html.insert', `<audio controls="true" width="90%" height="100%" src="${this.http.appendImagePath(path)}" style="vertical-align:middle"/>`, false);*/}
|
||||
{/*// this.mediumEditorInstance.pasteHTML(*/}
|
||||
{/*// `<audio controls="true" width="90%" height="100%" src="${this.http.appendImagePath(path)}" style="vertical-align:middle"/>`,*/}
|
||||
{/*// {cleanAttrs: []});*/}
|
||||
{/*}*/}
|
||||
{/*else if(file.mime_type.includes("application")){*/}
|
||||
{/*this.editor('file.insert', this.http.appendImagePath(path), file.name);*/}
|
||||
{/*// this.mediumEditorInstance.pasteHTML(*/}
|
||||
{/*// `*/}
|
||||
{/*// <file src=${this.http.appendImagePath(path)} style="display:inline-block;height:150px; width:150px;">*/}
|
||||
{/*// <div style="height:150px; width:150px; text-align:center; margin: 0 auto;box-shadow:0 10px 16px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19) !important;">*/}
|
||||
{/*// <svg fill="#999" height="150" viewBox="0 0 24 24" width="150" xmlns="http://www.w3.org/2000/svg">*/}
|
||||
{/*// <path d="M2 12.5C2 9.46 4.46 7 7.5 7H18c2.21 0 4 1.79 4 4s-1.79 4-4 4H9.5C8.12 15 7 13.88 7 12.5S8.12 10 9.5 10H17v2H9.41c-.55 0-.55 1 0 1H18c1.1 0 2-.9 2-2s-.9-2-2-2H7.5C5.57 9 4 10.57 4 12.5S5.57 16 7.5 16H17v2H7.5C4.46 18 2 15.54 2 12.5z"/>*/}
|
||||
{/*// <path d="M0 0h24v24H0V0z" fill="none"/>*/}
|
||||
{/*// </svg>*/}
|
||||
{/*// </div>*/}
|
||||
{/*// </div>*/}
|
||||
{/*// </file>*/}
|
||||
{/*// `,*/}
|
||||
{/*// {cleanAttrs: []});*/}
|
||||
{/*}*/}
|
||||
|
||||
{/*};*/}
|
||||
{/*// this.mediumEditorInstance.saveSelection();*/}
|
||||
{/*this.props.appstate.globalUI.showDialog(DIALOG.MEDIA.SELECT);*/}
|
||||
{/*}} style={{marginTop: this.helpStore.classData.type !== 'pay_per_course' ? 25 : 10}} icon={<AttachmentIcon/>} label="Attachments" primary={true} fullWidth={true} />*/}
|
||||
</div>
|
||||
</Card>
|
||||
</Affix>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Dialog
|
||||
title="Warning"
|
||||
actions={actions}
|
||||
modal={true}
|
||||
open={this.state.openedDialog}
|
||||
onRequestClose={() => this.handleClose()}
|
||||
>
|
||||
Make sure all of your data is correct before submitting.
|
||||
</Dialog>
|
||||
<Dialog
|
||||
title="Warning"
|
||||
actions={actionsBack}
|
||||
modal={true}
|
||||
contentStyle={{width: 350}}
|
||||
open={this.state.openedDialogBack}
|
||||
onRequestClose={() => this.handleBackClose()}
|
||||
>
|
||||
Are you sure you wanna go back ?
|
||||
</Dialog>
|
||||
|
||||
<Dialog
|
||||
title="Warning"
|
||||
actions={actionsDelete}
|
||||
modal={true}
|
||||
open={this.state.openDeleteDialog}
|
||||
onRequestClose={() => this.handleWarningDialog(false)}
|
||||
>
|
||||
Are you sure want to delete this item?
|
||||
</Dialog>
|
||||
|
||||
<Dialog
|
||||
title="Warning"
|
||||
actions={actionsEmpty}
|
||||
modal={true}
|
||||
contentStyle={{width: 350}}
|
||||
open={this.state.openedDialogEmpty}
|
||||
onRequestClose={() => this.handleEmptyClose()}
|
||||
>
|
||||
Title and content cannot be empty !
|
||||
</Dialog>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
238
src/common/pages/Help/index.js
Normal file
238
src/common/pages/Help/index.js
Normal file
@@ -0,0 +1,238 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import bind from 'bind-decorator';
|
||||
import {
|
||||
Card,
|
||||
FlatButton,
|
||||
Divider,
|
||||
RaisedButton,
|
||||
Toolbar,
|
||||
ToolbarGroup,
|
||||
ToolbarSeparator,
|
||||
Table,
|
||||
TableBody,
|
||||
TableHeader,
|
||||
TableHeaderColumn,
|
||||
TableRow,
|
||||
TableRowColumn,
|
||||
TextField,
|
||||
Dialog,
|
||||
Tab, Tabs,
|
||||
IconButton
|
||||
} from 'material-ui';
|
||||
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 ImageEdit from 'material-ui/svg-icons/image/edit';
|
||||
import EmptyComponent from '../EmptyComponent';
|
||||
import LoadingDialog from "../LoadingDialog";
|
||||
import Loader from 'react-loader-advanced';
|
||||
import {Link} from 'react-router-dom';
|
||||
import {LINKS} from "../../routes";
|
||||
import moment from 'moment';
|
||||
import {DIALOG} from "../../stores/global_ui";
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class Help extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
value: 0,
|
||||
edit : false,
|
||||
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.helpStore = props.appstate.help;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.globalUI.openLoading();
|
||||
this.helpStore.getList().then(res => {
|
||||
this.globalUI.closeLoading();
|
||||
});
|
||||
}
|
||||
|
||||
handleUpdateInput = (searchText) => {
|
||||
this.setState({
|
||||
searchText: searchText,
|
||||
});
|
||||
};
|
||||
|
||||
handleNewRequest = () => {
|
||||
this.setState({
|
||||
searchText: '',
|
||||
});
|
||||
};
|
||||
|
||||
tabsHandleChange = (value) => {
|
||||
this.setState({
|
||||
slideIndex: value,
|
||||
});
|
||||
};
|
||||
|
||||
deleteClicked = (id) => {
|
||||
this.setState({
|
||||
id : id,
|
||||
openedDelete: true
|
||||
});
|
||||
}
|
||||
|
||||
handleClickDelete = (id) => {
|
||||
this.helpStore.delete(id).then(res=>{
|
||||
this.setState({
|
||||
openedDelete: false,
|
||||
openSnackbarDelete: true
|
||||
});
|
||||
this.globalUI.openSnackbar("Successful Deleted Existing Data");
|
||||
|
||||
}).catch(err=>{
|
||||
console.log(err);
|
||||
this.globalUI.openSnackbar(err.message);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
handleCloseDelete = () => {
|
||||
this.setState({
|
||||
openedDelete: false
|
||||
})
|
||||
}
|
||||
|
||||
handleChange = (event, index, value) => this.setState({value});
|
||||
|
||||
search = (event)=>{
|
||||
if(event.target.value.length == 0){
|
||||
this.helpStore.isSearching = false;
|
||||
}
|
||||
else{
|
||||
this.helpStore.isSearching = true;
|
||||
this.helpStore.search(event.target.value);
|
||||
}
|
||||
}
|
||||
|
||||
goToForm = ()=>{
|
||||
this.props.history.push(LINKS.FORM_HELP);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const actionsDelete = [
|
||||
<FlatButton
|
||||
label="Cancel"
|
||||
primary={true}
|
||||
onClick={this.handleCloseDelete}
|
||||
/>,
|
||||
<FlatButton
|
||||
label="Delete"
|
||||
primary={true}
|
||||
onClick={() => this.handleClickDelete(this.state.id)}
|
||||
/>,
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="setting containerMiddle">
|
||||
<div className="row">
|
||||
<div className="col l12 m12 s12">
|
||||
<Tabs
|
||||
value={'help'}
|
||||
inkBarStyle={{background: 'transparent'}}
|
||||
className="tabsAkun"
|
||||
style={{background: 'transparent'}}
|
||||
>
|
||||
<Tab label="Help" value="help" className="buttonTabs buttonTabsActive">
|
||||
<div className="row">
|
||||
<div className="col l12 m12 s12">
|
||||
<Card className="animated fadeIn cardLite">
|
||||
<Toolbar className="toolbarCard" style={{backgroundColor: '#fff'}}>
|
||||
<ToolbarGroup>
|
||||
<SearchIcon style={{marginRight: 8, color: "#999"}}/>
|
||||
<TextField
|
||||
hintText="Search Help"
|
||||
style={{fontSize: 14}}
|
||||
hintStyle={{fontSize: 14}}
|
||||
underlineShow={false}
|
||||
onChange={this.search}
|
||||
/>
|
||||
</ToolbarGroup>
|
||||
<ToolbarGroup className="ToolbarGroupLast">
|
||||
<ToolbarSeparator/>
|
||||
<RaisedButton className="ToolbarGroupLastButton" icon={<AddIcon/>} label="New Help"
|
||||
primary={true} onClick={this.goToForm}/>
|
||||
</ToolbarGroup>
|
||||
</Toolbar>
|
||||
<Divider/>
|
||||
<div style={{paddingBottom: 5}}>
|
||||
<Loader show={this.globalUI.loadingVisibility} message={<LoadingDialog/>}
|
||||
messageStyle={{textAlign: 'center'}} backgroundStyle={{backgroundColor: 'rgba(255,255,255,0.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'}}>Title</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun" style={{height: 'auto'}}>Created At</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto', textAlign: 'right'}}>Action</TableHeaderColumn>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody displayRowCheckbox={false}>
|
||||
{(this.helpStore.list.length > 0) ? (this.helpStore.isSearching ? this.helpStore.filtered : this.helpStore.list).map((item, index) => {
|
||||
return (
|
||||
<TableRow key={item.id}>
|
||||
<TableRowColumn>
|
||||
<div>
|
||||
<Link to={`${LINKS.FORM_HELP}/${item.id}`} key={item.id}>{item.title}</Link>
|
||||
</div>
|
||||
</TableRowColumn>
|
||||
<TableRowColumn>{moment(item.created_at).format('DD MMMM YYYY, HH:mm:ss')}</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>
|
||||
</Loader>
|
||||
</div>
|
||||
<Dialog
|
||||
title="Warning"
|
||||
actions={actionsDelete}
|
||||
modal={true}
|
||||
open={this.state.openedDelete}
|
||||
onRequestClose={() => this.handleCloseDelete()}
|
||||
>
|
||||
Are you sure want to delete this data?
|
||||
</Dialog>
|
||||
{/* {this.state.edit ? <DialogCreate mode="update" defaultValue={Object.assign({},this.state.defaultValue)}/> : <DialogCreate mode="create"/>} */}
|
||||
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
302
src/common/pages/Inbox/Chat/index.js
Normal file
302
src/common/pages/Inbox/Chat/index.js
Normal file
@@ -0,0 +1,302 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import bind from 'bind-decorator';
|
||||
import {
|
||||
Card,
|
||||
CardActions,
|
||||
CardHeader,
|
||||
CardMedia,
|
||||
CardTitle,
|
||||
AutoComplete,
|
||||
CardText,
|
||||
FlatButton,
|
||||
List,
|
||||
ListItem,
|
||||
Divider,
|
||||
Snackbar,
|
||||
Tabs, Tab,
|
||||
RaisedButton,
|
||||
Toolbar,
|
||||
DatePicker,
|
||||
FontIcon,
|
||||
Table,
|
||||
TableBody,
|
||||
TableHeader,
|
||||
TableHeaderColumn,
|
||||
TableRow,
|
||||
TableRowColumn,
|
||||
MenuItem,
|
||||
Toggle,
|
||||
ToolbarGroup,
|
||||
FloatingActionButton,
|
||||
ToolbarSeparator,
|
||||
IconButton,
|
||||
ToolbarTitle,
|
||||
RadioButton,
|
||||
TextField,
|
||||
Paper,
|
||||
RadioButtonGroup
|
||||
} from 'material-ui';
|
||||
import {List as ListAntd, Avatar, Input} from 'antd';
|
||||
import {yellow500} from 'material-ui/styles/colors';
|
||||
import StarBorder from 'material-ui/svg-icons/toggle/star-border';
|
||||
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/action/delete';
|
||||
import ImageEdit from 'material-ui/svg-icons/image/edit';
|
||||
import EmptyComponent from '../../EmptyComponent';
|
||||
import {Link} from 'react-router-dom';
|
||||
import {LINKS} from "../../../routes";
|
||||
import './style.scss';
|
||||
import {appConfig} from "../../../config/app";
|
||||
import NumberFormat from 'react-number-format';
|
||||
import LoadingDialog from "../../LoadingDialog";
|
||||
import Loader from 'react-loader-advanced';
|
||||
import moment from 'moment';
|
||||
import {last,upperCase,get} from 'lodash';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class ChatComponent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.chatStore = props.appstate.message;
|
||||
this.state = {
|
||||
chatName : (this.chatStore.activerooms === '') ? "Please select user to start chatting" : this.chatStore.activerooms.name
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.http = props.appstate.http;
|
||||
this.userData = props.appstate.userData;
|
||||
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this.chatStore.getRooms();
|
||||
console.log(this.userData,'USER DATA')
|
||||
}
|
||||
|
||||
componentDidUpdate (){
|
||||
let rightThing = document.getElementById('rightContainer');
|
||||
if(rightThing){
|
||||
rightThing.scrollTop = rightThing.scrollHeight;
|
||||
}
|
||||
};
|
||||
|
||||
componentWillUnmount(){
|
||||
this.chatStore.reset();
|
||||
}
|
||||
|
||||
|
||||
handleChange = (chatSelected) => {
|
||||
this.chatStore.setRooms(chatSelected);
|
||||
this.setState({chatName : chatSelected.name})
|
||||
this.props.history.push(LINKS.INBOX + '/chat?r=' + chatSelected.id);
|
||||
this.scrollToBottom();
|
||||
};
|
||||
|
||||
sendMessage = () =>{
|
||||
this.chatStore.sendMessage();
|
||||
};
|
||||
|
||||
getChatDate = (created_at)=>{
|
||||
let dayDiffrent = moment(created_at).diff(moment(),'days');
|
||||
if(dayDiffrent == 0){
|
||||
return moment(created_at).format('H:mm');
|
||||
}
|
||||
else if(dayDiffrent == -1){
|
||||
return 'Yesterday'
|
||||
}
|
||||
else if(dayDiffrent < -1 && dayDiffrent >= -6){
|
||||
return moment(created_at).format('ddd');
|
||||
}
|
||||
else if(dayDiffrent < -6){
|
||||
return moment(created_at).format('M/D/YY');
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
<div className="row no-margin">
|
||||
<div className="col l12 m12 s12 no-padding">
|
||||
<Card className="animated fadeIn cardLite">
|
||||
<div className='containerChat'>
|
||||
<div className="row no-margin containerChatInner">
|
||||
<div className="col s4 m4 l4 no-padding ">
|
||||
<div className={'containerLeftListChat'}>
|
||||
<Toolbar className="toolbarCard header-page-chat-sticky"
|
||||
style={{backgroundColor: '#fff', borderBottom: '2px solid #ddd'}}>
|
||||
<ToolbarGroup>
|
||||
<ToolbarTitle style={{fontSize: 14, fontWeight: 500, color: '#32325d'}} text={'Chats'}/>
|
||||
</ToolbarGroup>
|
||||
</Toolbar>
|
||||
<Divider/>
|
||||
<div className={'containerLeftListChatInner'} style={{padding:'0px'}}>
|
||||
<ListAntd
|
||||
itemLayout="horizontal"
|
||||
dataSource={this.chatStore.chatrooms}
|
||||
renderItem={item => (
|
||||
<ListAntd.Item key={item.id} className={(item.id == this.chatStore.activerooms.id) ? 'active_chat' : 'unactive_chat'} onClick={()=>this.handleChange(item)}>
|
||||
<ListAntd.Item.Meta
|
||||
avatar={<Avatar style={{ backgroundColor: '#1976D2' ,color:'#FFF'}}>{item.name ? upperCase(item.name.substring(0,1)) : '-'}</Avatar>}
|
||||
title={<div style={{display:'flex',justifyContent:'space-between'}}><span style={{color : '#000'}}>{item.name}</span><p className="description_chat_p" style={{color:'#B7B7B7','fontSize':'11px'}}>{this.getChatDate(last(item.message).created_at)}</p></div>}
|
||||
description={<div style={{textOverflow: 'ellipsis',display:'flex',justifyContent:'space-between'}}><p className="description_chat_p">{(item.message.length == 0 )? 'Message empty' : ((last(item.message).message_sender_user_id === this.userData.user_id) ? 'You : ' : '')+`${last(item.message).message}` }</p><span className="new_message_count" style={{visibility:((item.unread_message > 0)?'visible':'hidden')}}>{item.unread_message}</span></div>}
|
||||
/>
|
||||
</ListAntd.Item>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col s8 m8 l8 no-padding ">
|
||||
{/*<ListAntd*/}
|
||||
{/*itemLayout="horizontal"*/}
|
||||
{/*dataSource={data}*/}
|
||||
{/*renderItem={item => (*/}
|
||||
{/*<ListAntd.Item>*/}
|
||||
{/*<ListAntd.Item.Meta*/}
|
||||
{/*avatar={<Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"/>}*/}
|
||||
{/*title={<a href="https://ant.design">{item.title}</a>}*/}
|
||||
{/*description="Ant Design, a design language for background applications, is refined by Ant UED Team"*/}
|
||||
{/*/>*/}
|
||||
{/*</ListAntd.Item>*/}
|
||||
{/*)}*/}
|
||||
{/*/>*/}
|
||||
<Toolbar className="toolbarCard header-page-chat-sticky"
|
||||
style={{
|
||||
backgroundColor: '#fff',
|
||||
borderBottom: '2px solid #ddd',
|
||||
borderLeft: '1px solid #ddd',
|
||||
borderRadius: 0
|
||||
}}>
|
||||
<ToolbarGroup>
|
||||
<ToolbarTitle style={{fontSize: 14, fontWeight: 500, color: '#32325d'}} text={this.state.chatName}/>
|
||||
</ToolbarGroup>
|
||||
</Toolbar>
|
||||
<Divider/>
|
||||
{this.chatStore.message.length > 0 ? (
|
||||
<div>
|
||||
<div className={'containerRightListChatInner'} id="rightContainer">
|
||||
{this.chatStore.message.map((message,index)=>{
|
||||
// if(moment(message.created_at).diff(moment(),'days') == 0){
|
||||
// return (<div className="chat-date-separator"><span>Today</span></div>)
|
||||
// }
|
||||
|
||||
|
||||
// else if(moment(message.created_at).diff(moment(),'days') == -1){
|
||||
// return (<div className="chat-date-separator"><span>Yesterday</span></div>)
|
||||
// }
|
||||
|
||||
if(message.yours_message == true || message.yours_message == "true"){
|
||||
return (
|
||||
<div className="chat-message self">
|
||||
<div className="chat-message-content-w">
|
||||
<div className="chat-message-content">{message.message}
|
||||
</div>
|
||||
</div>
|
||||
<div className="chat-message-date">{moment(message.created_at).format('HH:mm')}</div>
|
||||
<div className="chat-message-avatar"><img alt="" src="/assets/images/icon/icon-store24x.jpg"/></div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
else if(message.yours_message == false || message.yours_message == "false"){
|
||||
return (
|
||||
<div className={'chat-message'}>
|
||||
<div className={'chat-message-content-w'}>
|
||||
<div className={'messegesChat'}>{message.message}</div>
|
||||
</div>
|
||||
<Avatar style={{ backgroundColor: '#1976D2' ,color:'#FFF'}}>{message.user.email ? upperCase(message.user.email.substring(0,1)) : '-'}</Avatar>
|
||||
<div className="chat-message-date">{moment(message.created_at).format('HH:mm')}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})}
|
||||
|
||||
|
||||
{/*<div className="chat-date-separator"><span>Yesterday</span></div>*/}
|
||||
|
||||
{/*<div className={'chat-message'}>*/}
|
||||
{/*<div className={'chat-message-content-w'}>*/}
|
||||
{/*<div className={'messegesChat'}>Hallo Admin.....</div>*/}
|
||||
{/*</div>*/}
|
||||
{/*<div className={'chat-message-avatar'}>*/}
|
||||
{/*<img src="/assets/images/avatar3.jpg" alt=""/>*/}
|
||||
{/*</div>*/}
|
||||
{/*<div className="chat-message-date">9:12am</div>*/}
|
||||
{/*</div>*/}
|
||||
|
||||
{/*<div className={'chat-message'}>*/}
|
||||
{/*<div className={'chat-message-content-w'}>*/}
|
||||
{/*<div className={'messegesChat'}>Slept train nearby a its is design size agreeable. And check*/}
|
||||
{/*cons, but countries the was to such any founding company*/}
|
||||
{/*</div>*/}
|
||||
{/*</div>*/}
|
||||
{/*<div className={'chat-message-avatar'}>*/}
|
||||
{/*<img src="/assets/images/avatar3.jpg" alt=""/>*/}
|
||||
{/*</div>*/}
|
||||
{/*<div className="chat-message-date">9:12am</div>*/}
|
||||
{/*</div>*/}
|
||||
|
||||
{/*<div className={'chat-message'}>*/}
|
||||
{/*<div className={'chat-message-content-w'}>*/}
|
||||
{/*<div className={'messegesChat'}>Slept train nearby a its is design size agreeable. And check*/}
|
||||
{/*cons, but countries the was to such any founding company*/}
|
||||
{/*</div>*/}
|
||||
{/*</div>*/}
|
||||
{/*<div className={'chat-message-avatar'}>*/}
|
||||
{/*<img src="/assets/images/avatar3.jpg" alt=""/>*/}
|
||||
{/*</div>*/}
|
||||
{/*<div className="chat-message-date">9:12am</div>*/}
|
||||
{/*</div>*/}
|
||||
|
||||
{/*<div className={'chat-message'}>*/}
|
||||
{/*<div className={'chat-message-content-w'}>*/}
|
||||
{/*<div className={'messegesChat'}>Slept train nearby a its is design size agreeable. And check*/}
|
||||
{/*cons, but countries the was to such any founding company*/}
|
||||
{/*</div>*/}
|
||||
{/*</div>*/}
|
||||
{/*<div className={'chat-message-avatar'}>*/}
|
||||
{/*<img src="/assets/images/avatar3.jpg" alt=""/>*/}
|
||||
{/*</div>*/}
|
||||
{/*<div className="chat-message-date">9:12am</div>*/}
|
||||
{/*</div>*/}
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<Toolbar className="toolbarCard header-page-chat-bottom-sticky"
|
||||
style={{
|
||||
borderTop: '1px solid #ddd',
|
||||
borderLeft: '1px solid #ddd',
|
||||
borderRadius: 0,
|
||||
backgroundColor: '#f5f1ee',
|
||||
marginRight:-1
|
||||
}}>
|
||||
<ToolbarGroup className={'fullWidthButton'}>
|
||||
<Input placeholder="Type your message here... " onChange={(e)=>this.chatStore.writeMessage(e.target.value)} value={this.chatStore.lineMessage} onPressEnter={()=>this.sendMessage()}/>
|
||||
</ToolbarGroup>
|
||||
</Toolbar>
|
||||
</div>
|
||||
)
|
||||
:
|
||||
<div className={'containerRightListChatInner'} style={{textAlign:'center'}} >
|
||||
<img src='/assets/images/emptyState/empty-chat.png' style={{width:'50%'}}/>
|
||||
<h2>Select user to start chatting</h2>
|
||||
<h3 style={{color:'#bababa'}}>Connect with store or customer to make transaction more fun and easy</h3>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
208
src/common/pages/Inbox/Chat/style.scss
Normal file
208
src/common/pages/Inbox/Chat/style.scss
Normal file
@@ -0,0 +1,208 @@
|
||||
.picture-container {
|
||||
position: relative;
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
margin-top: 10px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.store-picture {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 100px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.middle {
|
||||
transition: .7s ease;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
-ms-transform: translate(-50%, -50%);
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.store-name {
|
||||
padding-top: 20px;
|
||||
padding-left: 15px;
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.store-join {
|
||||
padding-left: 15px;
|
||||
color: #fff;
|
||||
font-weight: 300;
|
||||
font-size: 1.0em;
|
||||
}
|
||||
|
||||
.banner-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.store-banner {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.middle-banner {
|
||||
transition: .7s ease;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
-ms-transform: translate(-50%, -50%);
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.media-container {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.picture-container:hover .store-picture {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.picture-container:hover .middle {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.media-container:hover .store-banner {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.media-container:hover .middle-banner {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.header-page-chat-sticky {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.header-page-chat-bottom-sticky {
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
z-index: 10;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.containerChat {
|
||||
height: calc(100vh - 140px);
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.containerLeftListChatInner {
|
||||
padding: 18px;
|
||||
overflow: auto;
|
||||
height: calc(100vh - 196px);
|
||||
background-color: #f6f7f8;
|
||||
}
|
||||
|
||||
.containerRightListChatInner {
|
||||
overflow: auto;
|
||||
height: calc(100vh - 240px);
|
||||
padding-left: 7.5% !important;
|
||||
padding-right: 7.5% !important;
|
||||
border-left: 1px solid #ddd;
|
||||
padding-top: 50px !important;
|
||||
//padding-bottom: 135px !important;
|
||||
}
|
||||
|
||||
.chat-message {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.messegesChat {
|
||||
padding: 15px 35px;
|
||||
background-color: #fff9f0;
|
||||
color: #594939;
|
||||
max-width: 400px;
|
||||
display: inline-block;
|
||||
margin-bottom: -20px;
|
||||
margin-left: 20px;
|
||||
border-radius: 20px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.chat-message-avatar {
|
||||
display: inline-block;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
.chat-message-avatar img {
|
||||
width: 40px;
|
||||
height: auto;
|
||||
border-radius: 30px;
|
||||
display: inline-block;
|
||||
-webkit-box-shadow: 0 0 0 10px #fff;
|
||||
box-shadow: 0 0 0 10px #fff;
|
||||
}
|
||||
|
||||
.chat-message-date {
|
||||
display: inline-block;
|
||||
vertical-align: bottom;
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
font-size: .72rem;
|
||||
color: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.chat-date-separator span {
|
||||
display: inline-block;
|
||||
background-color: #fff;
|
||||
padding: 0 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.chat-date-separator {
|
||||
text-align: center;
|
||||
color: rgba(0, 0, 0, 0.3);
|
||||
font-size: .81rem;
|
||||
position: relative;
|
||||
margin: 40px 0;
|
||||
}
|
||||
|
||||
.chat-date-separator:before {
|
||||
content: "";
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
height: 1px;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.chat-message.self {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.chat-message.self .chat-message-content {
|
||||
background-color: #f0f9ff;
|
||||
color: #2A4E7F;
|
||||
margin-right: 20px;
|
||||
margin-left: 0;
|
||||
padding: 15px 35px;
|
||||
max-width: 400px;
|
||||
display: inline-block;
|
||||
margin-bottom: -20px;
|
||||
border-radius: 20px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar {
|
||||
width: 8px !important;
|
||||
height: 6px !important;
|
||||
}
|
||||
142
src/common/pages/Inbox/index.js
Normal file
142
src/common/pages/Inbox/index.js
Normal file
@@ -0,0 +1,142 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import bind from 'bind-decorator';
|
||||
import {
|
||||
Card,
|
||||
CardActions,
|
||||
CardHeader,
|
||||
CardMedia,
|
||||
CardTitle,
|
||||
AutoComplete,
|
||||
CardText,
|
||||
FlatButton,
|
||||
List,
|
||||
ListItem,
|
||||
Divider,
|
||||
Snackbar,
|
||||
Tabs, Tab,
|
||||
RaisedButton,
|
||||
Toolbar,
|
||||
DatePicker,
|
||||
FontIcon,
|
||||
Table,
|
||||
TableBody,
|
||||
TableHeader,
|
||||
TableHeaderColumn,
|
||||
TableRow,
|
||||
TableRowColumn,
|
||||
MenuItem,
|
||||
Toggle,
|
||||
ToolbarGroup,
|
||||
FloatingActionButton,
|
||||
ToolbarSeparator,
|
||||
IconButton,
|
||||
ToolbarTitle,
|
||||
RadioButton,
|
||||
TextField,
|
||||
Paper,
|
||||
RadioButtonGroup
|
||||
} from 'material-ui';
|
||||
import {yellow500} from 'material-ui/styles/colors';
|
||||
import StarBorder from 'material-ui/svg-icons/toggle/star-border';
|
||||
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/action/delete';
|
||||
import ImageEdit from 'material-ui/svg-icons/image/edit';
|
||||
import EmptyComponent from '../EmptyComponent';
|
||||
import {Link} from 'react-router-dom';
|
||||
import {LINKS} from "../../routes";
|
||||
import './style.scss';
|
||||
import {appConfig} from "../../config/app";
|
||||
import NumberFormat from 'react-number-format';
|
||||
import LoadingDialog from "../LoadingDialog";
|
||||
import Loader from 'react-loader-advanced';
|
||||
import Chat from './Chat';
|
||||
import Notification from '../Notification';
|
||||
|
||||
export const MESSAGE_TABS = {
|
||||
CHAT: 'chat',
|
||||
NOTIFICATION: 'notification',
|
||||
};
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class InboxComponent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.taskStore = props.appstate.task;
|
||||
this.state = {
|
||||
tabSelected: MESSAGE_TABS.CHAT,
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.http = props.appstate.http;
|
||||
this.authStore = props.appstate.auth;
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
this.messageStore = props.appstate.message;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.history.push(LINKS.INBOX +`/${this.messageStore.selectedTab}`)
|
||||
// const {match: {params: {tab: tabSelected}}} = this.props;
|
||||
// console.log(this.props);
|
||||
// if (!tabSelected) {
|
||||
// console.log('kmlkmlml')
|
||||
// this.props.history.push(LINKS.INBOX + "/chat");
|
||||
// this.messageStore.changeTab('chat');
|
||||
// } else {
|
||||
// this.handleChange(tabSelected);
|
||||
// }
|
||||
// console.log(this.globalUI.storeTabSelected)
|
||||
|
||||
}
|
||||
|
||||
handleChange = (tabSelected) => {
|
||||
this.setState({
|
||||
tabSelected: tabSelected,
|
||||
});
|
||||
this.props.history.push(LINKS.INBOX+'/'+tabSelected);
|
||||
this.messageStore.changeTab(tabSelected)
|
||||
};
|
||||
|
||||
getContent() {
|
||||
switch (this.messageStore.selectedTab) {
|
||||
case MESSAGE_TABS.NOTIFICATION:
|
||||
return <Notification historyPush={this.props.history.push}/>
|
||||
case MESSAGE_TABS.CHAT:
|
||||
return <Chat history={this.props.history}/>
|
||||
default:
|
||||
return <Chat history={this.props.history}/>
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
<div className="inbox containerMiddle">
|
||||
<div className="row no-margin" style={{marginBottom:40}}>
|
||||
<div className="col l12 m12 s12">
|
||||
<Tabs
|
||||
value={this.state.tabSelected}
|
||||
onChange={this.handleChange}
|
||||
inkBarStyle={{background: 'transparent'}}
|
||||
className="tabsAkun"
|
||||
style={{background: 'transparent'}}
|
||||
>
|
||||
<Tab label="Chat" value="chat"
|
||||
className={(this.messageStore.selectedTab === 'chat') ? "buttonTabs buttonTabsActive" : 'buttonTabs'}>
|
||||
</Tab>
|
||||
<Tab label="Notification" value="notification"
|
||||
className={(this.messageStore.selectedTab === 'notification') ? "buttonTabs buttonTabsActive" : 'buttonTabs'}>
|
||||
</Tab>
|
||||
|
||||
</Tabs>
|
||||
|
||||
{this.getContent()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
54
src/common/pages/Inbox/style.scss
Normal file
54
src/common/pages/Inbox/style.scss
Normal file
@@ -0,0 +1,54 @@
|
||||
.inbox {
|
||||
margin-top: 35px;
|
||||
.container {
|
||||
padding: 25px;
|
||||
|
||||
.ant-card {
|
||||
background: #fff;
|
||||
border-radius: 0px;
|
||||
font-size: 12px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition: all .3s;
|
||||
}
|
||||
.ant-card-head {
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
background: #fff;
|
||||
border-bottom: 0px solid #e9e9e9;
|
||||
padding: 0 24px;
|
||||
}
|
||||
.ant-card:hover {
|
||||
box-shadow: 4px 4px 40px rgba(0, 0, 0, .05);
|
||||
border-color: transparent;
|
||||
}
|
||||
.ant-card-body-dashboard {
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.label-form {
|
||||
font-size: 14px;
|
||||
line-height: 30px;
|
||||
color: rgb(153, 153, 153);
|
||||
text-shadow: rgb(255, 255, 255) 0px 1px 0px;
|
||||
margin-bottom: -8px;
|
||||
}
|
||||
|
||||
.backgroundImage {
|
||||
height: 182px;
|
||||
background-image: url('/assets/images/material3.jpg');
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
cursor: pointer;
|
||||
min-height: 75px;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
85
src/common/pages/InviteConfirmation/form.js
Normal file
85
src/common/pages/InviteConfirmation/form.js
Normal file
@@ -0,0 +1,85 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import {Form, Input, Button, Select, DatePicker, Icon} from 'antd'
|
||||
const {Option, OptGroup} = Select;
|
||||
|
||||
const FormItem = Form.Item;
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
class InviteConfirmationForm extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
console.log('InviteConfirmationForm loaded!')
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const {getFieldDecorator} = this.props.form;
|
||||
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
xs: {span: 24},
|
||||
sm: {span: 6},
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: {span: 24},
|
||||
sm: {span: 14},
|
||||
},
|
||||
};
|
||||
|
||||
const tailFormItemLayout = {
|
||||
wrapperCol: {
|
||||
xs: {
|
||||
span: 24,
|
||||
offset: 0,
|
||||
},
|
||||
sm: {
|
||||
span: 14,
|
||||
offset: 6,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const formItemLayoutWithOutLabel = {
|
||||
wrapperCol: {
|
||||
xs: {span: 24, offset: 0},
|
||||
sm: {span: 14, offset: 6},
|
||||
},
|
||||
};
|
||||
|
||||
const formItemLayoutFull = {
|
||||
wrapperCol: {
|
||||
xs: {span: 24, offset: 0},
|
||||
sm: {span: 24, offset: 0},
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<Form>
|
||||
<FormItem label={"Your new Password"}>
|
||||
{getFieldDecorator('password', {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Cannot be empty',
|
||||
},
|
||||
{
|
||||
min: 4,
|
||||
message: 'at least 4 character'
|
||||
}
|
||||
]
|
||||
})(<Input type={"password"} />)}
|
||||
</FormItem>
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default Form.create()(InviteConfirmationForm);
|
||||
120
src/common/pages/InviteConfirmation/index.js
Normal file
120
src/common/pages/InviteConfirmation/index.js
Normal file
@@ -0,0 +1,120 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import {
|
||||
Form,
|
||||
Input,
|
||||
Button,
|
||||
Select,
|
||||
DatePicker,
|
||||
Icon,
|
||||
message,
|
||||
Spin
|
||||
} from 'antd'
|
||||
import InviteForm from './form';
|
||||
import css from 'reactcss';
|
||||
import {LINKS} from './../../routes';
|
||||
import './style.scss';
|
||||
|
||||
const {Option, OptGroup} = Select;
|
||||
const FormItem = Form.Item;
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class InviteConfirmationComponent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
isLoading: false
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.style = css({
|
||||
default: {
|
||||
container: {
|
||||
minHeight: '100vh'
|
||||
},
|
||||
loginForm: {
|
||||
paddingTop: '15%'
|
||||
}
|
||||
}
|
||||
})
|
||||
this.authStore = props.appstate.auth;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
console.log('InviteConfirmationComponent loaded!');
|
||||
this.query = this
|
||||
.props
|
||||
.location
|
||||
.search
|
||||
.substr(1)
|
||||
.split('&')
|
||||
.reduce((q, value) => {
|
||||
const [k,
|
||||
v] = value.split('=');
|
||||
q[k] = v;
|
||||
return q;
|
||||
}, {});
|
||||
}
|
||||
|
||||
confirm() {
|
||||
let message = message;
|
||||
this.setState({isLoading: true})
|
||||
this
|
||||
.formInstance
|
||||
.validateFields((err, fields) => {
|
||||
if (err) {
|
||||
return console.error(err)
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
this
|
||||
.authStore
|
||||
.acceptInvite(this.query.token, fields.password)
|
||||
.then(res => {
|
||||
// message.success(res.message);
|
||||
this
|
||||
.props
|
||||
.history
|
||||
.push(LINKS.LOGIN);
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err);
|
||||
message.error(err.message);
|
||||
this.setState({isLoading: false})
|
||||
});
|
||||
}, 1000);
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
<div className="login" style={this.style.container}>
|
||||
<div className="login-box">
|
||||
<Spin spinning={this.state.isLoading}>
|
||||
<div className="header">
|
||||
<div>
|
||||
<img alt="logo" src="/assets/images/green.png"/>
|
||||
</div>
|
||||
<p>Accelerate</p>
|
||||
</div>
|
||||
<div style={{
|
||||
textAlign: "center"
|
||||
}}>
|
||||
<InviteForm ref={form => this.formInstance = form}/>
|
||||
<Button
|
||||
style={{
|
||||
width: "100%",
|
||||
marginBottom: 10
|
||||
}}
|
||||
type="primary"
|
||||
size="large"
|
||||
onClick={e => this.confirm()}>Confirm</Button>
|
||||
</div>
|
||||
</Spin>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
41
src/common/pages/InviteConfirmation/style.scss
Normal file
41
src/common/pages/InviteConfirmation/style.scss
Normal file
@@ -0,0 +1,41 @@
|
||||
.invite-confirmation {
|
||||
.background {
|
||||
height: 100%;
|
||||
overflow-y: hidden;
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
.ant-form-explain {
|
||||
text-align: left;
|
||||
}
|
||||
.login-box {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin: -160px 0 0 -160px;
|
||||
width: 320px;
|
||||
height: 320px;
|
||||
padding: 36px;
|
||||
box-shadow: 0 0 100px rgba(0, 0, 0, .08);
|
||||
.header {
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
margin-bottom: 24px;
|
||||
img {
|
||||
width: 40px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
span {
|
||||
vertical-align: text-bottom;
|
||||
font-size: 16px;
|
||||
text-transform: uppercase;
|
||||
display: inline-block;
|
||||
}
|
||||
p {
|
||||
font-size: 16px;
|
||||
text-transform: uppercase;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
85
src/common/pages/InviteConfirmationLogin/form.js
Normal file
85
src/common/pages/InviteConfirmationLogin/form.js
Normal file
@@ -0,0 +1,85 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import {Form, Input, Button, Select, DatePicker, Icon} from 'antd'
|
||||
const {Option, OptGroup} = Select;
|
||||
|
||||
const FormItem = Form.Item;
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
class InviteConfirmationForm extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
console.log('InviteConfirmationForm loaded!')
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const {getFieldDecorator} = this.props.form;
|
||||
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
xs: {span: 24},
|
||||
sm: {span: 6},
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: {span: 24},
|
||||
sm: {span: 14},
|
||||
},
|
||||
};
|
||||
|
||||
const tailFormItemLayout = {
|
||||
wrapperCol: {
|
||||
xs: {
|
||||
span: 24,
|
||||
offset: 0,
|
||||
},
|
||||
sm: {
|
||||
span: 14,
|
||||
offset: 6,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const formItemLayoutWithOutLabel = {
|
||||
wrapperCol: {
|
||||
xs: {span: 24, offset: 0},
|
||||
sm: {span: 14, offset: 6},
|
||||
},
|
||||
};
|
||||
|
||||
const formItemLayoutFull = {
|
||||
wrapperCol: {
|
||||
xs: {span: 24, offset: 0},
|
||||
sm: {span: 24, offset: 0},
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<Form>
|
||||
<FormItem label={"Your new Password"}>
|
||||
{getFieldDecorator('password', {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Cannot be empty',
|
||||
},
|
||||
{
|
||||
min: 4,
|
||||
message: 'at least 4 character'
|
||||
}
|
||||
]
|
||||
})(<Input type={"password"} />)}
|
||||
</FormItem>
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default Form.create()(InviteConfirmationForm);
|
||||
165
src/common/pages/InviteConfirmationLogin/index.js
Normal file
165
src/common/pages/InviteConfirmationLogin/index.js
Normal file
@@ -0,0 +1,165 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import {
|
||||
Form,
|
||||
Input,
|
||||
Button,
|
||||
Select,
|
||||
DatePicker,
|
||||
Icon,
|
||||
message,
|
||||
Spin
|
||||
} from 'antd'
|
||||
import InviteForm from './form';
|
||||
import css from 'reactcss';
|
||||
import {LINKS} from './../../routes';
|
||||
import './style.scss';
|
||||
import { Link } from 'react-router-dom';
|
||||
import {Modal} from 'antd';
|
||||
import { withRouter } from 'react-router';
|
||||
|
||||
const {Option, OptGroup} = Select;
|
||||
const FormItem = Form.Item;
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
@withRouter
|
||||
export default class InviteConfirmationLoginComponent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
isLoading: false
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.style = css({
|
||||
default: {
|
||||
container: {
|
||||
minHeight: '100vh'
|
||||
},
|
||||
loginForm: {
|
||||
paddingTop: '15%'
|
||||
}
|
||||
}
|
||||
})
|
||||
console.log(props);
|
||||
this.authStore = props.appstate.auth;
|
||||
this.query = this
|
||||
.props
|
||||
.location
|
||||
.search
|
||||
.substr(1)
|
||||
.split('&')
|
||||
.reduce((q, value) => {
|
||||
const [k,
|
||||
v] = value.split('=');
|
||||
q[k] = v;
|
||||
return q;
|
||||
}, {});
|
||||
|
||||
this.http = props.appstate.http;
|
||||
|
||||
if(!this.query.token) {
|
||||
Modal.error({
|
||||
title: 'Token doesn\'t exist',
|
||||
content: '',
|
||||
onOk() {
|
||||
props.history.push(LINKS.LOGIN)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
console.log('InviteConfirmationComponent loaded!');
|
||||
}
|
||||
|
||||
confirm() {
|
||||
let message = message;
|
||||
this.setState({isLoading: true})
|
||||
this
|
||||
.formInstance
|
||||
.validateFields((err, fields) => {
|
||||
if (err) {
|
||||
return console.error(err)
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
this
|
||||
.authStore
|
||||
.acceptInvite(this.query.token || '', fields.password)
|
||||
.then(res => {
|
||||
// message.success(res.message);
|
||||
this
|
||||
.props
|
||||
.history
|
||||
.push(LINKS.LOGIN);
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err);
|
||||
message.error(err.message);
|
||||
this.setState({isLoading: false})
|
||||
});
|
||||
}, 1000);
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
<div className="login" style={this.style.container}>
|
||||
<div className="login-box">
|
||||
<Spin spinning={this.state.isLoading}>
|
||||
<div className="header">
|
||||
<div>
|
||||
<img alt="logo" src="/assets/images/green.png"/>
|
||||
</div>
|
||||
<p>Accelerate</p>
|
||||
</div>
|
||||
<div style={{
|
||||
textAlign: "center"
|
||||
}}>
|
||||
You've been invited to {this.query.entity || ''}. {!this.authStore.isLoggedIn && "Please login or register to continue"}
|
||||
|
||||
{this.authStore.isLoggedIn && <Button
|
||||
style={{
|
||||
width: "100%",
|
||||
marginBottom: 10
|
||||
}}
|
||||
type="primary"
|
||||
size="large"
|
||||
onClick={() => {
|
||||
console.log('onclick');
|
||||
this.http.post('invite_user_accept_existing', {
|
||||
token: this.query.token
|
||||
}).then(() => {
|
||||
message.info('Accept invite success');
|
||||
this.props.history.push(LINKS.LOGIN);
|
||||
})
|
||||
}}
|
||||
>Accept</Button>}
|
||||
|
||||
{!this.authStore.isLoggedIn && <Link to={LINKS.REGISTER + "?"+ Object.keys(this.query).map(k => `${k}=${this.query[k]}`).join('&')}>
|
||||
<Button
|
||||
style={{
|
||||
width: "100%",
|
||||
marginBottom: 10
|
||||
}}
|
||||
size="large">Register</Button>
|
||||
</Link>}
|
||||
{!this.authStore.isLoggedIn && <Link to={LINKS.LOGIN + "?"+ Object.keys(this.query).map(k => `${k}=${this.query[k]}`).join('&')}>
|
||||
<Button
|
||||
style={{
|
||||
width: "100%",
|
||||
marginBottom: 10
|
||||
}}
|
||||
type="primary"
|
||||
size="large">Login</Button>
|
||||
</Link>}
|
||||
</div>
|
||||
</Spin>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
41
src/common/pages/InviteConfirmationLogin/style.scss
Normal file
41
src/common/pages/InviteConfirmationLogin/style.scss
Normal file
@@ -0,0 +1,41 @@
|
||||
.invite-confirmation {
|
||||
.background {
|
||||
height: 100%;
|
||||
overflow-y: hidden;
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
.ant-form-explain {
|
||||
text-align: left;
|
||||
}
|
||||
.login-box {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin: -160px 0 0 -160px;
|
||||
width: 320px;
|
||||
height: 320px;
|
||||
padding: 36px;
|
||||
box-shadow: 0 0 100px rgba(0, 0, 0, .08);
|
||||
.header {
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
margin-bottom: 24px;
|
||||
img {
|
||||
width: 40px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
span {
|
||||
vertical-align: text-bottom;
|
||||
font-size: 16px;
|
||||
text-transform: uppercase;
|
||||
display: inline-block;
|
||||
}
|
||||
p {
|
||||
font-size: 16px;
|
||||
text-transform: uppercase;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
228
src/common/pages/Items/Active/index.js
Normal file
228
src/common/pages/Items/Active/index.js
Normal file
@@ -0,0 +1,228 @@
|
||||
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
|
||||
} 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 EyeIcon from 'material-ui/svg-icons/image/remove-red-eye';
|
||||
import DeleteIcon from 'material-ui/svg-icons/content/delete-sweep';
|
||||
import ImageEdit from 'material-ui/svg-icons/image/edit';
|
||||
import EmptyComponent from '../../EmptyComponent';
|
||||
import LoadingDialog from "../../LoadingDialog";
|
||||
import Loader from 'react-loader-advanced';
|
||||
import {Row, Col} from 'antd';
|
||||
|
||||
import '../style.scss';
|
||||
import {appConfig} from "../../../config/app";
|
||||
import {Link} from 'react-router-dom';
|
||||
import {LINKS} from "../../../routes";
|
||||
import {ItemCard} from '../ItemCard';
|
||||
import InfiniteScroll from 'react-infinite-scroller';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class Active extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
value: 0,
|
||||
statusBanned: "Banned",
|
||||
statusSoldOut: "Sold Out"
|
||||
};
|
||||
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.rewardStore = props.appstate.reward;
|
||||
|
||||
this.myStoreItem = props.appstate.myStoreItem;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// this.myStoreItem.isSearching = false;
|
||||
this.myStoreItem.setRequestQuery({visible : true});
|
||||
this.myStoreItem.getAll();
|
||||
}
|
||||
|
||||
componentWillUnmount(){
|
||||
this.myStoreItem.isSearching = false;
|
||||
this.myStoreItem.reset();
|
||||
}
|
||||
|
||||
search = (event)=>{
|
||||
console.log("dataSearch",event.target.value);
|
||||
if(event.target.value.length == 0){
|
||||
this.myStoreItem.isSearching = false;
|
||||
}
|
||||
else{
|
||||
this.myStoreItem.isSearching = true;
|
||||
this.myStoreItem.search(event.target.value);
|
||||
}
|
||||
}
|
||||
|
||||
deleteClicked = (id) => {
|
||||
this.state.id = id;
|
||||
this.setState({
|
||||
openedDelete: true
|
||||
});
|
||||
}
|
||||
|
||||
handleClickDelete = (id) => {
|
||||
this.rewardStore.deleteReward(id);
|
||||
this.setState({
|
||||
openedDelete: false,
|
||||
openSnackbarDelete: true
|
||||
});
|
||||
this.globalUI.openSnackbar("Successful Deleted Existing Reward");
|
||||
}
|
||||
|
||||
handleCloseDelete = () => {
|
||||
this.setState({
|
||||
openedDelete: false
|
||||
})
|
||||
}
|
||||
|
||||
handleChange = (event, index, value) => this.setState({value});
|
||||
|
||||
loadMore = ()=>{
|
||||
console.log('RUNNss');
|
||||
if(this.myStoreItem.data.length > 0){
|
||||
this.myStoreItem.nextPage(true);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
console.log(this.myStoreItem.data.length);
|
||||
|
||||
const actionsDelete = [
|
||||
<FlatButton
|
||||
label="Cancel"
|
||||
primary={true}
|
||||
onClick={this.handleCloseDelete}
|
||||
/>,
|
||||
<FlatButton
|
||||
label="Delete"
|
||||
primary={true}
|
||||
onClick={() => this.handleClickDelete(this.state.id)}
|
||||
/>,
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="row">
|
||||
<div className="col l12 m12 s12">
|
||||
<Card className="animated fadeIn cardLite">
|
||||
<Toolbar className="toolbarCard radius4" style={{backgroundColor: '#fff'}}>
|
||||
<ToolbarGroup>
|
||||
<SearchIcon style={{marginRight: 8, color: "#999"}}/>
|
||||
<TextField
|
||||
hintText="Search Active By Name"
|
||||
style={{fontSize: 14}}
|
||||
hintStyle={{fontSize: 14}}
|
||||
underlineShow={false}
|
||||
onChange={this.search}
|
||||
/>
|
||||
</ToolbarGroup>
|
||||
{/*<ToolbarGroup className="ToolbarGroupLast">*/}
|
||||
{/*<ToolbarSeparator/>*/}
|
||||
{/*<Link to={`${LINKS.FORM_ITEMS}`}>*/}
|
||||
{/*<RaisedButton className="ToolbarGroupLastButton" icon={<AddIcon/>} label="New Items"*/}
|
||||
{/*primary={true}/>*/}
|
||||
{/*</Link>*/}
|
||||
{/*</ToolbarGroup>*/}
|
||||
</Toolbar>
|
||||
|
||||
{/*<div style={{paddingBottom: 5}}>*/}
|
||||
{/*<Loader show={false} message={<LoadingDialog/>}*/}
|
||||
{/*messageStyle={{textAlign: 'center'}} backgroundStyle={{backgroundColor: 'rgba(255,255,255,0.5)'}}>*/}
|
||||
|
||||
{/*</Loader>*/}
|
||||
{/*</div>*/}
|
||||
<Dialog
|
||||
title="Warning"
|
||||
actions={actionsDelete}
|
||||
modal={true}
|
||||
open={this.state.openedDelete}
|
||||
onRequestClose={() => this.handleCloseDelete()}
|
||||
>
|
||||
Are you sure want to delete this data?
|
||||
</Dialog>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InfiniteScroll pageStart={0} loadMore={this.loadMore} hasMore={!(this.myStoreItem.maxPage == this.myStoreItem.currentPage)}>
|
||||
<Row className="row rowItem" gutter={8}>
|
||||
{/* <Col className="gutter-row col animated fadeIn" span={4}>
|
||||
<Link to={`${LINKS.FORM_UPLOAD}`} style={{color:'#424770'}}>
|
||||
<div className="flex add-new"
|
||||
style={{
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
height: 323
|
||||
}}>
|
||||
<div>
|
||||
<FontIcon className="material-icons icon-add ">add</FontIcon>
|
||||
</div>
|
||||
Add new item
|
||||
</div>
|
||||
</Link>
|
||||
</Col>*/}
|
||||
{(this.myStoreItem.isSearching ? this.myStoreItem.dataFiltered : this.myStoreItem.data).filter(f=>f.stock!="0.00").map(item => {
|
||||
return (<Col key={item.id} className="gutter-row col" span={4} style={{marginBottom: 20}}>
|
||||
<div className="gutter-box"><ItemCard data={item}/></div>
|
||||
</Col>)
|
||||
})}
|
||||
</Row>
|
||||
</InfiniteScroll>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
259
src/common/pages/Items/All/index.js
Normal file
259
src/common/pages/Items/All/index.js
Normal file
@@ -0,0 +1,259 @@
|
||||
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
|
||||
} 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 EyeIcon from 'material-ui/svg-icons/image/remove-red-eye';
|
||||
import DeleteIcon from 'material-ui/svg-icons/content/delete-sweep';
|
||||
import ImageEdit from 'material-ui/svg-icons/image/edit';
|
||||
import EmptyComponent from '../../EmptyComponent';
|
||||
import LoadingDialog from "../../LoadingDialog";
|
||||
import Loader from 'react-loader-advanced';
|
||||
import {Row, Col} from 'antd';
|
||||
|
||||
import '../style.scss';
|
||||
import {appConfig} from "../../../config/app";
|
||||
import {Link} from 'react-router-dom';
|
||||
import {LINKS} from "../../../routes";
|
||||
import {ItemCard} from '../ItemCard';
|
||||
import InfiniteScroll from 'react-infinite-scroller';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class All extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);``
|
||||
this.props = props;
|
||||
this.state = {
|
||||
searchText:'',
|
||||
value: 0,
|
||||
statusBanned: "Banned",
|
||||
statusSoldOut: "Sold Out"
|
||||
};
|
||||
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.userData = props.appstate.userData;
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
this.rewardStore = props.appstate.reward;
|
||||
this.userData = props.appstate.userData;
|
||||
this.myStoreItem = props.appstate.myStoreItem;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// this.myStoreItem.isSearching = false;
|
||||
if(this.userData.role == 'store') {
|
||||
this.myStoreItem.getAll();
|
||||
}
|
||||
if(this.userData.role == 'administrator') {
|
||||
this.myStoreItem.setRequestQuery({user_store_id : this.props.id});
|
||||
console.log('ini id',this.props.id);
|
||||
this.myStoreItem.getAll();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount(){
|
||||
this.myStoreItem.isSearching = false;
|
||||
this.myStoreItem.reset();
|
||||
}
|
||||
|
||||
deleteClicked = (id) => {
|
||||
this.state.id = id;
|
||||
this.setState({
|
||||
openedDelete: true
|
||||
});
|
||||
}
|
||||
|
||||
search = (event)=>{
|
||||
console.log("dataSearch",event.target.value);
|
||||
if(event.target.value.length == 0){
|
||||
this.myStoreItem.isSearching = false;
|
||||
}
|
||||
else{
|
||||
this.myStoreItem.isSearching = true;
|
||||
this.myStoreItem.search(event.target.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
handleClickDelete = (id) => {
|
||||
this.rewardStore.deleteReward(id);
|
||||
this.setState({
|
||||
openedDelete: false,
|
||||
openSnackbarDelete: true
|
||||
});
|
||||
this.globalUI.openSnackbar("Successful Deleted Existing Reward");
|
||||
}
|
||||
|
||||
handleCloseDelete = () => {
|
||||
this.setState({
|
||||
openedDelete: false
|
||||
})
|
||||
}
|
||||
|
||||
handleChange = (event, index, value) => this.setState({value});
|
||||
|
||||
loadMore = ()=>{
|
||||
console.log('RUNNss');
|
||||
if(this.myStoreItem.data.length > 0){
|
||||
this.myStoreItem.nextPage(true);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
console.log(this.myStoreItem.data.length);
|
||||
|
||||
const actionsDelete = [
|
||||
<FlatButton
|
||||
label="Cancel"
|
||||
primary={true}
|
||||
onClick={this.handleCloseDelete}
|
||||
/>,
|
||||
<FlatButton
|
||||
label="Delete"
|
||||
primary={true}
|
||||
onClick={() => this.handleClickDelete(this.state.id)}
|
||||
/>,
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="row">
|
||||
<div className="col l12 m12 s12">
|
||||
<Card className="animated fadeIn cardLite">
|
||||
<Toolbar className="toolbarCard radius4" style={{backgroundColor: '#fff'}}>
|
||||
<ToolbarGroup>
|
||||
<SearchIcon style={{marginRight: 8, color: "#999"}}/>
|
||||
<TextField
|
||||
hintText="Search All by Name"
|
||||
style={{fontSize: 14}}
|
||||
hintStyle={{fontSize: 14}}
|
||||
underlineShow={false}
|
||||
onChange={this.search}
|
||||
/>
|
||||
</ToolbarGroup>
|
||||
{/*<ToolbarGroup className="ToolbarGroupLast">*/}
|
||||
{/*<ToolbarSeparator/>*/}
|
||||
{/*<Link to={`${LINKS.FORM_ITEMS}`}>*/}
|
||||
{/*<RaisedButton className="ToolbarGroupLastButton" icon={<AddIcon/>} label="New Items"*/}
|
||||
{/*primary={true}/>*/}
|
||||
{/*</Link>*/}
|
||||
{/*</ToolbarGroup>*/}
|
||||
</Toolbar>
|
||||
|
||||
{/*<div style={{paddingBottom: 5}}>*/}
|
||||
{/*<Loader show={false} message={<LoadingDialog/>}*/}
|
||||
{/*messageStyle={{textAlign: 'center'}} backgroundStyle={{backgroundColor: 'rgba(255,255,255,0.5)'}}>*/}
|
||||
|
||||
{/*</Loader>*/}
|
||||
{/*</div>*/}
|
||||
<Dialog
|
||||
title="Warning"
|
||||
actions={actionsDelete}
|
||||
modal={true}
|
||||
open={this.state.openedDelete}
|
||||
onRequestClose={() => this.handleCloseDelete()}
|
||||
>
|
||||
Are you sure want to delete this data?
|
||||
</Dialog>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InfiniteScroll pageStart={0} loadMore={this.loadMore} hasMore={true}>
|
||||
<Row className="row rowItem" gutter={8}>
|
||||
{(this.userData.role === 'store' && this.userData.entity_permission.can_store_change_item) ?
|
||||
<Col className="gutter-row col animated fadeIn" span={4}>
|
||||
<Link to={`${LINKS.FORM_ITEMS}`} style={{color: '#424770'}}>
|
||||
<div className="flex add-new"
|
||||
style={{
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
height: 323
|
||||
}}>
|
||||
<div>
|
||||
<FontIcon className="material-icons icon-add ">add</FontIcon>
|
||||
</div>
|
||||
Add new item
|
||||
</div>
|
||||
</Link>
|
||||
</Col> : ""
|
||||
}
|
||||
|
||||
{(this.userData.role === 'administrator') ?
|
||||
<Col className="gutter-row col animated fadeIn" span={4}>
|
||||
<Link to={`${LINKS.FORM_ITEMS}/${this.props.id}`} style={{color: '#424770'}}>
|
||||
<div className="flex add-new"
|
||||
style={{
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
height: 323
|
||||
}}>
|
||||
<div>
|
||||
<FontIcon className="material-icons icon-add ">add</FontIcon>
|
||||
</div>
|
||||
Add new item
|
||||
</div>
|
||||
</Link>
|
||||
</Col> : ""
|
||||
}
|
||||
|
||||
{(this.myStoreItem.isSearching ? this.myStoreItem.dataFiltered : this.myStoreItem.data).map(item => {
|
||||
return (<Col key={item.id} className="gutter-row col" span={4} style={{marginBottom: 20}}>
|
||||
<div className="gutter-box"><ItemCard data={item}/></div>
|
||||
</Col>)
|
||||
})}
|
||||
</Row>
|
||||
</InfiniteScroll>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
227
src/common/pages/Items/Banned/index.js
Normal file
227
src/common/pages/Items/Banned/index.js
Normal file
@@ -0,0 +1,227 @@
|
||||
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
|
||||
} 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 ImageEdit from 'material-ui/svg-icons/image/edit';
|
||||
import EmptyComponent from '../../EmptyComponent';
|
||||
import LoadingDialog from "../../LoadingDialog";
|
||||
import Loader from 'react-loader-advanced';
|
||||
import '../style.scss';
|
||||
import {appConfig} from "../../../config/app";
|
||||
import {Link} from 'react-router-dom';
|
||||
import {LINKS} from "../../../routes";
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class Banned extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
value: 0,
|
||||
};
|
||||
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.rewardStore = props.appstate.reward;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.globalUI.openLoading();
|
||||
this.rewardStore.getRewardList().then(res => {
|
||||
this.globalUI.closeLoading();
|
||||
});
|
||||
}
|
||||
|
||||
handleUpdateInput = (searchText) => {
|
||||
this.setState({
|
||||
searchText: searchText,
|
||||
});
|
||||
};
|
||||
|
||||
handleNewRequest = () => {
|
||||
this.setState({
|
||||
searchText: '',
|
||||
});
|
||||
};
|
||||
|
||||
tabsHandleChange = (value) => {
|
||||
this.setState({
|
||||
slideIndex: value,
|
||||
});
|
||||
};
|
||||
|
||||
deleteClicked = (id) => {
|
||||
this.state.id = id;
|
||||
this.setState({
|
||||
openedDelete: true
|
||||
});
|
||||
}
|
||||
|
||||
handleClickDelete = (id) => {
|
||||
this.rewardStore.deleteReward(id);
|
||||
this.setState({
|
||||
openedDelete: false,
|
||||
openSnackbarDelete: true
|
||||
});
|
||||
this.globalUI.openSnackbar("Successful Deleted Existing Reward");
|
||||
}
|
||||
|
||||
handleCloseDelete = () => {
|
||||
this.setState({
|
||||
openedDelete: false
|
||||
})
|
||||
}
|
||||
|
||||
handleChange = (event, index, value) => this.setState({value});
|
||||
|
||||
render() {
|
||||
|
||||
const actionsDelete = [
|
||||
<FlatButton
|
||||
label="Cancel"
|
||||
primary={true}
|
||||
onClick={this.handleCloseDelete}
|
||||
/>,
|
||||
<FlatButton
|
||||
label="Delete"
|
||||
primary={true}
|
||||
onClick={() => this.handleClickDelete(this.state.id)}
|
||||
/>,
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="row">
|
||||
<div className="col l12 m12 s12">
|
||||
<Card className="animated fadeIn cardLite">
|
||||
<Toolbar className="toolbarCard" style={{backgroundColor: '#fff'}}>
|
||||
<ToolbarGroup>
|
||||
<SearchIcon style={{marginRight: 8, color: "#999"}}/>
|
||||
<TextField
|
||||
hintText="Search Banned"
|
||||
style={{fontSize: 14}}
|
||||
hintStyle={{fontSize: 14}}
|
||||
underlineShow={false}
|
||||
/>
|
||||
</ToolbarGroup>
|
||||
<ToolbarGroup className="ToolbarGroupLast">
|
||||
<ToolbarSeparator/>
|
||||
<Link to={`${LINKS.REWARD}`}>
|
||||
<RaisedButton className="ToolbarGroupLastButton" icon={<AddIcon/>} label="New Reward" primary={true}/>
|
||||
</Link>
|
||||
</ToolbarGroup>
|
||||
</Toolbar>
|
||||
<Divider/>
|
||||
<div style={{paddingBottom: 5}}>
|
||||
<Loader show={this.globalUI.loadingVisibility} message={<LoadingDialog/>}
|
||||
messageStyle={{textAlign: 'center'}} backgroundStyle={{backgroundColor: 'rgba(255,255,255,0.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'}}>ID</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun" style={{height: 'auto'}}>Reward
|
||||
Name</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun" style={{height: 'auto'}}>Reward
|
||||
Type</TableHeaderColumn>
|
||||
<TableHeaderColumn className="TableHeaderColumnAkun"
|
||||
style={{height: 'auto', textAlign: 'right'}}>Action</TableHeaderColumn>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody displayRowCheckbox={false}>
|
||||
{!this.rewardStore.isRewardEmpty ? this.rewardStore.rewardList.map((item, index) => {
|
||||
return (
|
||||
<TableRow key={item.id}>
|
||||
<TableRowColumn>
|
||||
<Link
|
||||
to={`${LINKS.REWARD}/${item.id}`}
|
||||
>
|
||||
{item.id.split('-')[0]}
|
||||
</Link>
|
||||
</TableRowColumn>
|
||||
<TableRowColumn>{item.name}</TableRowColumn>
|
||||
<TableRowColumn>{item.reward_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>
|
||||
</Loader>
|
||||
</div>
|
||||
<Dialog
|
||||
title="Warning"
|
||||
actions={actionsDelete}
|
||||
modal={true}
|
||||
open={this.state.openedDelete}
|
||||
onRequestClose={() => this.handleCloseDelete()}
|
||||
>
|
||||
Are you sure want to delete this data?
|
||||
</Dialog>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
87
src/common/pages/Items/FormItems/FormItemAdmin.js
Normal file
87
src/common/pages/Items/FormItems/FormItemAdmin.js
Normal file
@@ -0,0 +1,87 @@
|
||||
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 ImageEdit from 'material-ui/svg-icons/image/edit';
|
||||
import EmptyComponent from '../../EmptyComponent';
|
||||
import LoadingDialog from "../../LoadingDialog";
|
||||
import Loader from 'react-loader-advanced';
|
||||
import {appConfig} from "../../../config/app";
|
||||
import {Link} from 'react-router-dom';
|
||||
import {LINKS} from "../../../routes";
|
||||
import moment from 'moment';
|
||||
import {DIALOG} from "../../../stores/global_ui";
|
||||
import FormItems from './FormItems';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class FormItemAdmin extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
value: 0,
|
||||
edit : false,
|
||||
defaultValue : {}
|
||||
};
|
||||
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.storeListStore = props.appstate.storeList;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
console.log('ini detail form',this.props.match.params.id)
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
<FormItems id={this.props.match.params.id} history={this.props.history}/>
|
||||
)
|
||||
}
|
||||
}
|
||||
1045
src/common/pages/Items/FormItems/FormItems.js
Normal file
1045
src/common/pages/Items/FormItems/FormItems.js
Normal file
File diff suppressed because it is too large
Load Diff
953
src/common/pages/Items/FormItems/FormPromotion.js
Normal file
953
src/common/pages/Items/FormItems/FormPromotion.js
Normal file
@@ -0,0 +1,953 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import {
|
||||
Card,
|
||||
FlatButton,
|
||||
Divider,
|
||||
RaisedButton,
|
||||
Toolbar,
|
||||
MenuItem,
|
||||
ToolbarGroup,
|
||||
IconButton,
|
||||
ToolbarTitle,
|
||||
Dialog,
|
||||
Toggle
|
||||
} from 'material-ui';
|
||||
import SaveIcon from 'material-ui/svg-icons/content/save';
|
||||
import DeleteIcon from 'material-ui/svg-icons/action/delete';
|
||||
import AddIcon from 'material-ui/svg-icons/content/add';
|
||||
import { Upload, Icon, Modal, Input, Select, Switch, message, Button as ButtonAntd } from 'antd';
|
||||
import '../style.scss';
|
||||
import {LINKS} from "../../../routes";
|
||||
import uuid from 'uuid';
|
||||
import {appConfig} from "../../../config/app";
|
||||
import NumberFormat from 'react-number-format';
|
||||
|
||||
const InputGroup = Input.Group;
|
||||
const { TextArea } = Input;
|
||||
const Option = Select.Option;
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class FormPromotion extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.rewardStore = props.appstate.reward;
|
||||
this.state = {
|
||||
openedDialog: false,
|
||||
openDeleteDialog : false,
|
||||
value: 1,
|
||||
searchText: '',
|
||||
slideIndex: 0,
|
||||
openedDialogBack: false,
|
||||
reward_type: "Choose Reward Type",
|
||||
expanded: false,
|
||||
previewVisible: false,
|
||||
previewImage: '',
|
||||
fileList: [],
|
||||
fileLength: 0,
|
||||
fileMainExist: false,
|
||||
formData: {
|
||||
custom_fields: []
|
||||
},
|
||||
viewOnly : false,
|
||||
mode: 'create',
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.http = props.appstate.http;
|
||||
this.authStore = props.appstate.auth;
|
||||
this.userData = props.appstate.userData;
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
this.categoryStore = props.appstate.category;
|
||||
this.itemStore = props.appstate.item;
|
||||
this.myStoreItem = props.appstate.myStoreItem;
|
||||
this.userData = props.appstate.userData;
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
console.log('ini promotion')
|
||||
if(this.userData.role === 'store' && !this.userData.entity_permission.can_store_change_item){
|
||||
this.setState({viewOnly : true})
|
||||
}
|
||||
|
||||
this.categoryStore.getCategoryList();
|
||||
if(this.props.match.params.id){
|
||||
this.globalUI.showDialogLoading();
|
||||
await this.itemStore.getDetail(this.props.match.params.id);
|
||||
let data = {};
|
||||
if(typeof this.itemStore.selectedData.data[0].custom_fields === 'object'){
|
||||
data = Object.assign(this.itemStore.selectedData.data[0], {custom_fields: []});
|
||||
}else {
|
||||
data = Object.assign(this.itemStore.selectedData.data[0], {});
|
||||
}
|
||||
this.setState({formData: data});
|
||||
console.log("DATA",data);
|
||||
let images = [];
|
||||
if(!data.images.main && data.images.gallery.length == 0){
|
||||
console.log('no main images');
|
||||
this.setState({fileMainExist: false, fileLength: 0});
|
||||
}else if(data.images.gallery.length == 0){
|
||||
this.setState({fileMainExist: true, fileLength: 2});
|
||||
const name = data.images.main.split('/')[2];
|
||||
const fileName = name.split('.')[0];
|
||||
images.push(
|
||||
{
|
||||
uid: name,
|
||||
name: fileName,
|
||||
status: 'done',
|
||||
url: appConfig.imageUrl+data.images.main,
|
||||
path: data.images.main,
|
||||
type: 'main'
|
||||
}
|
||||
);
|
||||
}else{
|
||||
this.setState({fileMainExist: true, fileLength: 1+data.images.gallery.length});
|
||||
const name = data.images.main.split('/')[2];
|
||||
const fileName = name.split('.')[0];
|
||||
images.push(
|
||||
{
|
||||
uid: name,
|
||||
name: fileName,
|
||||
status: 'done',
|
||||
url: appConfig.imageUrl+data.images.main,
|
||||
path: data.images.main,
|
||||
type: 'main'
|
||||
}
|
||||
);
|
||||
|
||||
data.images.gallery.map(item => {
|
||||
const name = item.split('/')[2];
|
||||
const fileName = name.split('.')[0];
|
||||
if(item == data.images.main){
|
||||
return;
|
||||
}
|
||||
images.push(
|
||||
{
|
||||
uid: name,
|
||||
name: fileName,
|
||||
status: 'done',
|
||||
url: appConfig.imageUrl+item,
|
||||
path: item,
|
||||
type: 'gallery'
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
this.setState({fileList: images, mode: 'edit'});
|
||||
console.log(this.state.fileList);
|
||||
console.log("fileLength",this.state.fileLength);
|
||||
console.log("fileMainExist",this.state.fileMainExist);
|
||||
}else{
|
||||
this.setState({fileList: this.itemStore.listImages});
|
||||
console.log(this.state.fileList.slice(), 'asd');
|
||||
}
|
||||
console.log(this.state.mode, 'mode')
|
||||
}
|
||||
|
||||
handleCancel = () => this.setState({ previewVisible: false });
|
||||
|
||||
|
||||
handleOpen = () => {
|
||||
this.setState({openedDialog: true});
|
||||
};
|
||||
|
||||
handleClose = () => {
|
||||
this.setState({openedDialog: false});
|
||||
};
|
||||
|
||||
postData = () => {
|
||||
console.log("ngepost");
|
||||
this.setState({openedDialog: false});
|
||||
|
||||
const data = Object.assign({
|
||||
user_store_id: this.props.id
|
||||
}, this.state.formData);
|
||||
|
||||
if (this.state.fileList.length > 0) {
|
||||
data.images = {
|
||||
main: this.state.fileList[0].path,
|
||||
gallery: this.state.fileList.filter((it, index) => index !== 0).map(f => f.path)
|
||||
};
|
||||
}else{
|
||||
data.images = {
|
||||
gallery : []
|
||||
}
|
||||
}
|
||||
|
||||
const custom_fields = this.state.formData.custom_fields.reduce((cf, c) => {
|
||||
|
||||
cf[c.label] = c.value;
|
||||
|
||||
return cf;
|
||||
}, {});
|
||||
|
||||
data.custom_fields = custom_fields;
|
||||
console.log(data, 'data post');
|
||||
if(this.userData.role == 'store') {
|
||||
this.itemStore.create(data)
|
||||
.then(async () => {
|
||||
await message.success('Success Added New Item');
|
||||
await this.myStoreItem.getAll();
|
||||
this.props.history.push(LINKS.ITEMS);
|
||||
});
|
||||
}
|
||||
else if(this.userData.role == 'administrator'){
|
||||
this.itemStore.create(data)
|
||||
.then(async () => {
|
||||
await message.success('Success Added New Item');
|
||||
await this.myStoreItem.setRequestQuery({user_store_id : this.props.id});
|
||||
await this.myStoreItem.getAll();
|
||||
this.props.history.push(`${LINKS.STORES_LIST}/${this.props.id}`);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
deleteData = () => {
|
||||
this.itemStore.delete(this.props.match.params.id)
|
||||
.then(async () => {
|
||||
await message.success('Success Delete The Item');
|
||||
if(this.userData.role === 'store') {
|
||||
await this.myStoreItem.getAll();
|
||||
this.props.history.push(LINKS.ITEMS);
|
||||
}
|
||||
else if(this.userData.role === 'administrator'){
|
||||
await this.myStoreItem.setRequestQuery({user_store_id : this.itemStore.selectedData.data[0].user_store_id});
|
||||
await this.myStoreItem.getAll();
|
||||
this.props.history.goBack();
|
||||
//this.props.history.push(`${LINKS.STORES_LIST}/${this.itemStore.selectedData.data[0].user_store_id}`);
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
editData = () => {
|
||||
console.log("fileList",this.state.fileList);
|
||||
console.log("editData");
|
||||
this.setState({openedDialog: false});
|
||||
|
||||
const data = Object.assign({}, this.state.formData);
|
||||
|
||||
|
||||
if (this.state.fileList.length > 0) {
|
||||
let imageGallery= this.state.fileList.filter(f=>f.type!=='main').map(f=>f.path);
|
||||
|
||||
//if gallery empty insert main image for gallery
|
||||
if(imageGallery.length == 0){
|
||||
imageGallery = this.state.fileList.filter(f=>f.type=='main').map(f=>f.path);
|
||||
}
|
||||
|
||||
data.images = {
|
||||
main: this.state.fileList[0].path,
|
||||
gallery: imageGallery
|
||||
}
|
||||
}
|
||||
else if(this.state.fileList.length == 0){
|
||||
data.images = {
|
||||
gallery : []
|
||||
}
|
||||
}
|
||||
|
||||
const custom_fields = this.state.formData.custom_fields.reduce((cf, c) => {
|
||||
|
||||
cf[c.label] = c.value;
|
||||
|
||||
return cf;
|
||||
}, {});
|
||||
|
||||
data.custom_fields = custom_fields;
|
||||
delete data.id;
|
||||
console.log("data mau diedit",data);
|
||||
|
||||
this.itemStore.update(this.props.match.params.id, data)
|
||||
.then(async () => {
|
||||
await message.success('Success Edited The Item');
|
||||
if(this.userData.role === 'store'){
|
||||
await this.myStoreItem.getAll();
|
||||
this.props.history.push(LINKS.ITEMS);
|
||||
}
|
||||
else if(this.userData.role === 'administrator'){
|
||||
await this.myStoreItem.setRequestQuery({user_store_id : this.itemStore.selectedData.data[0].user_store_id});
|
||||
await this.myStoreItem.getAll();
|
||||
// this.props.history.push(`${LINKS.STORES_LIST}/${this.itemStore.selectedData.data[0].user_store_id}`);
|
||||
this.props.history.goBack();
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
handleBackClose = () => {
|
||||
this.setState({openedDialogBack: false})
|
||||
};
|
||||
|
||||
handleBackOpen = () => {
|
||||
this.setState({openedDialogBack: true});
|
||||
};
|
||||
|
||||
triggerOnChange() {
|
||||
|
||||
}
|
||||
handleChange = ({ fileList }) => {this.setState({ fileList }); console.log(fileList, 'remove')};
|
||||
|
||||
handleMin = () => {
|
||||
console.log(this.state.formData);
|
||||
}
|
||||
uploaderHandler({file, onProgress}) {
|
||||
console.log(file, 'upload');
|
||||
console.log("fileLength", this.state.fileLength);
|
||||
console.log("fileMainExist", this.state.fileMainExist);
|
||||
this.http.upload(file)
|
||||
.then(res => {
|
||||
const {fileList} = this.state;
|
||||
let newFileList = fileList.filter((obj)=>{
|
||||
if(!obj.lastModified){
|
||||
return true;
|
||||
}
|
||||
|
||||
})
|
||||
if(!this.state.fileMainExist){
|
||||
newFileList.push({
|
||||
uid: newFileList.length,
|
||||
name: file.name,
|
||||
status: 'done',
|
||||
url: this.http.appendImagePath(res.path),
|
||||
path: res.path,
|
||||
type: 'main'
|
||||
});
|
||||
}
|
||||
else{
|
||||
newFileList.push({
|
||||
uid: newFileList.length,
|
||||
name: file.name,
|
||||
status: 'done',
|
||||
url: this.http.appendImagePath(res.path),
|
||||
path: res.path,
|
||||
type: 'gallery'
|
||||
});
|
||||
}
|
||||
|
||||
console.log("update fileList",fileList);
|
||||
console.log("new fileList",newFileList);
|
||||
this.setState({fileList : newFileList});
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
addCustomField() {
|
||||
const {custom_fields} = this.state.formData;
|
||||
|
||||
custom_fields.push({
|
||||
id: uuid.v4(),
|
||||
label: 'label-'+custom_fields.length,
|
||||
value: '',
|
||||
});
|
||||
|
||||
this.setState({
|
||||
formData: {
|
||||
...this.state.formData,
|
||||
custom_fields
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
removeCustomField(index){
|
||||
const {custom_fields} = this.state.formData;
|
||||
|
||||
custom_fields.splice(index,1);
|
||||
this.setState({
|
||||
formData: {
|
||||
...this.state.formData,
|
||||
custom_fields
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
changeCustomFieldLabel(i, v) {
|
||||
const {custom_fields} = this.state.formData;
|
||||
|
||||
custom_fields[i].label = v;
|
||||
|
||||
this.setState({
|
||||
formData: {
|
||||
...this.state.formData,
|
||||
custom_fields
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
changeCustomFieldValue(i, v) {
|
||||
const {custom_fields} = this.state.formData;
|
||||
|
||||
custom_fields[i].value = v;
|
||||
|
||||
this.setState({
|
||||
formData: {
|
||||
...this.state.formData,
|
||||
custom_fields
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
handleWarningDialog = (bool)=>{
|
||||
this.setState({
|
||||
openDeleteDialog : bool
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const { previewVisible, previewImage, fileList } = this.state;
|
||||
|
||||
const uploadButton = (
|
||||
<div>
|
||||
<Icon type="plus" />
|
||||
<div className="ant-upload-text">Upload</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const actions = [
|
||||
<FlatButton
|
||||
label="Cancel"
|
||||
primary={true}
|
||||
style={{marginRight: 10}}
|
||||
onClick={this.handleClose}
|
||||
/>,
|
||||
<RaisedButton
|
||||
label={(this.props.id ? "Input" : "Edit")}
|
||||
primary={true}
|
||||
disabled={this.itemStore.isLoading}
|
||||
onClick={(this.props.id ? this.postData : this.editData) }
|
||||
/>,
|
||||
];
|
||||
|
||||
const actionsDelete = [
|
||||
<FlatButton
|
||||
label="Cancel"
|
||||
primary={true}
|
||||
style={{marginRight: 10}}
|
||||
onClick={()=>this.handleWarningDialog(false)}
|
||||
/>,
|
||||
<RaisedButton
|
||||
label={"Delete"}
|
||||
primary={true}
|
||||
disabled={this.itemStore.isLoading}
|
||||
onClick={this.deleteData}
|
||||
/>,
|
||||
];
|
||||
|
||||
const actionsBack = [
|
||||
<FlatButton
|
||||
label="No"
|
||||
primary={true}
|
||||
style={{marginRight: 10}}
|
||||
onClick={this.handleBackClose}
|
||||
/>,
|
||||
<RaisedButton
|
||||
label="Yes"
|
||||
primary={true}
|
||||
onClick={() => this.props.history.goBack()}
|
||||
/>,
|
||||
];
|
||||
|
||||
const wrapperText = key => ele => React.cloneElement(ele, {
|
||||
value: this.state.formData[key],
|
||||
onChange: (e) => {
|
||||
if(key === "regular_price"){
|
||||
if(e.target.value.indexOf("-") > -1){
|
||||
this.setState({
|
||||
formData: {
|
||||
...this.state.formData,
|
||||
[key]: 0,
|
||||
}
|
||||
}, () => this.triggerOnChange());
|
||||
}
|
||||
else{
|
||||
this.setState({
|
||||
formData: {
|
||||
...this.state.formData,
|
||||
[key]: parseInt(e.target.value.replace(/\,/g,''),10),
|
||||
}
|
||||
}, () => this.triggerOnChange());
|
||||
}
|
||||
}
|
||||
else if(key === "stock"){
|
||||
if(e.target.value.indexOf("-") > -1){
|
||||
this.setState({
|
||||
formData: {
|
||||
...this.state.formData,
|
||||
[key]: 0,
|
||||
}
|
||||
}, () => this.triggerOnChange());
|
||||
}
|
||||
else if(e.target.value.slice(-1) === "," || e.target.value.slice(-1) === "." || e.target.value.slice(-1) === "-"){
|
||||
//do nothing
|
||||
}
|
||||
else{
|
||||
this.setState({
|
||||
formData: {
|
||||
...this.state.formData,
|
||||
[key]: e.target.value,
|
||||
}
|
||||
}, () => this.triggerOnChange());
|
||||
}
|
||||
}
|
||||
else if(key === "weight"){
|
||||
if(e.target.value.slice(-1) === "," || e.target.value.slice(-1) === "." || e.target.value.slice(-1) === "-"){
|
||||
//do nothing
|
||||
}
|
||||
else{
|
||||
this.setState({
|
||||
formData: {
|
||||
...this.state.formData,
|
||||
[key]: e.target.value,
|
||||
}
|
||||
}, () => this.triggerOnChange());
|
||||
}
|
||||
}
|
||||
else{
|
||||
this.setState({
|
||||
formData: {
|
||||
...this.state.formData,
|
||||
[key]: e.target.value,
|
||||
}
|
||||
}, () => this.triggerOnChange());
|
||||
}
|
||||
|
||||
console.log("value",this.state.formData[key]);
|
||||
console.log("value2",e.target.value);
|
||||
console.log("key",key);
|
||||
}
|
||||
});
|
||||
|
||||
const wrapperSelect = key => ele => React.cloneElement(ele, {
|
||||
value: this.state.formData[key],
|
||||
onChange: (e, k, v) => {
|
||||
this.setState({
|
||||
formData: {
|
||||
...this.state.formData,
|
||||
[key]: e,
|
||||
}
|
||||
}, () => this.triggerOnChange());
|
||||
}
|
||||
});
|
||||
|
||||
const wrapperToggle = key => ele => React.cloneElement(ele, {
|
||||
checked: this.state.formData[key],
|
||||
onChange: (e) => {
|
||||
this.setState({
|
||||
formData: {
|
||||
...this.state.formData,
|
||||
[key]: e,
|
||||
}
|
||||
}, () => this.triggerOnChange());
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
|
||||
<div style={{marginTop: 35}}>
|
||||
<div className="row">
|
||||
<div className="col s12">
|
||||
<Card className="animated fadeIn cardLite" style={{marginLeft: 12, marginRight: 12}}>
|
||||
<Toolbar className="toolbarCard" style={{backgroundColor: '#fff'}}>
|
||||
<ToolbarGroup>
|
||||
<IconButton
|
||||
iconClassName="material-icons"
|
||||
tooltip="Back"
|
||||
style={{marginLeft: '-10px'}}
|
||||
onClick={this.handleBackOpen}
|
||||
>
|
||||
arrow_back
|
||||
</IconButton>
|
||||
<ToolbarTitle style={{fontSize: 14, fontWeight: 500, color: '#32325d'}} text={'Promotion\'s Detail '}/>
|
||||
</ToolbarGroup>
|
||||
{
|
||||
(this.userData.role === 'store' && this.userData.entity_permission.can_store_change_item || this.userData.role === 'administrator' ) &&
|
||||
<ToolbarGroup>
|
||||
{/*<Button>Submit</Button>*/}
|
||||
{(this.userData.role === 'store' ? this.props.match.params.id ? <RaisedButton onClick={()=>this.handleWarningDialog(true)} icon={<DeleteIcon/>} label="Delete" primary={true} style={{marginRight : '1px'}}/> : '' : this.props.id ? '' : <RaisedButton onClick={()=>this.handleWarningDialog(true)} icon={<DeleteIcon/>} label="Delete" primary={true} style={{marginRight : '1px'}}/> ) }
|
||||
<RaisedButton onClick={this.handleOpen} icon={<SaveIcon/>} label="Save" primary={true} />
|
||||
</ToolbarGroup>
|
||||
}
|
||||
|
||||
</Toolbar>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
<div className={"row"}>
|
||||
<div className={"col s12"}>
|
||||
<div className="row">
|
||||
<div className={"col s7"}>
|
||||
<Card className="animated fadeIn cardLite">
|
||||
<div style={{padding: '14px'}}>
|
||||
<div className="row">
|
||||
<div className="row">
|
||||
<h2 className='photo-title'>
|
||||
Information
|
||||
</h2>
|
||||
</div>
|
||||
<Divider style={{marginBottom: 20}}/>
|
||||
<div className="row">
|
||||
<div className="col m6 l6">
|
||||
<p className="label-form">Name</p>
|
||||
{wrapperText("name")(
|
||||
<Input disabled={this.state.viewOnly} placeholder="E.g. Radio" autosize />
|
||||
)}
|
||||
</div>
|
||||
<div className="col m6 l6">
|
||||
<p className="label-form">Category</p>
|
||||
{/*{wrapperSelect("category_id")(*/}
|
||||
{/*<Select disabled={this.state.viewOnly} style={{width: '100%',overflow: 'scroll'}}>*/}
|
||||
{/*{this.categoryStore.categoryList.map(c => {*/}
|
||||
{/*return <Option key={c.id} value={c.id}>{c.name}</Option>*/}
|
||||
{/*})}*/}
|
||||
{/*</Select>*/}
|
||||
{/*)}*/}
|
||||
<Select defaultValue="Promotion" style={{width: '100%',overflow: 'scroll'}} disabled>
|
||||
<Option value="Promotion">Promotion</Option>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col m12 l12">
|
||||
<p className="label-form">Description</p>
|
||||
{wrapperText("description")(
|
||||
<TextArea disabled={this.state.viewOnly} placeholder="E.g. Radio 1993, sony from Japan" autosize />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<div className="row">
|
||||
<h2 className='photo-title'>
|
||||
Other Options
|
||||
</h2>
|
||||
</div>
|
||||
<Divider style={{marginBottom: 20}}/>
|
||||
<div className="row">
|
||||
<div className="col m12 l12">
|
||||
<div className={"row"}>
|
||||
<div className={"col s6"}>
|
||||
<p className="label-form">Pre-Order</p>
|
||||
</div>
|
||||
<div className={"col s6"} style={{textAlign: 'right'}}>
|
||||
{wrapperToggle("preorder")(
|
||||
<Switch disabled={this.state.viewOnly} checkedChildren={<Icon type="check" />} unCheckedChildren={<Icon type="cross" />} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col m12 l12">
|
||||
<div className={"row"}>
|
||||
<div className={"col s6"}>
|
||||
<p className="label-form">Use Weight as Stock</p>
|
||||
</div>
|
||||
<div className={"col s6"} style={{textAlign: 'right'}}>
|
||||
{wrapperToggle("use_weight_as_stock")(
|
||||
<Switch disabled={this.state.viewOnly} checkedChildren={<Icon type="check" />} unCheckedChildren={<Icon type="cross" />} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col m12 l12">
|
||||
<div className={"row"}>
|
||||
<div className={"col s6"}>
|
||||
<p className="label-form">Active</p>
|
||||
</div>
|
||||
<div className={"col s6"} style={{textAlign: 'right'}}>
|
||||
{wrapperToggle("visible")(
|
||||
<Switch disabled={this.state.viewOnly} checkedChildren={<Icon type="check" />} unCheckedChildren={<Icon type="cross" />} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <div className="row">
|
||||
<div className="col m6 l6">
|
||||
<p className="label-form">Condition</p>
|
||||
<SelectField
|
||||
value={this.state.selectedType}
|
||||
onChange={this.handleChangeType}
|
||||
fullWidth={true}
|
||||
>
|
||||
<MenuItem value={1} primaryText="Never" />
|
||||
<MenuItem value={2} primaryText="Every Night" />
|
||||
<MenuItem value={3} primaryText="Weeknights" />
|
||||
<MenuItem value={4} primaryText="Weekends" />
|
||||
<MenuItem value={5} primaryText="Weekly" />
|
||||
</SelectField>
|
||||
</div>
|
||||
</div> */}
|
||||
{/* <div className="row">
|
||||
<div className="col m6 l6">
|
||||
<p className="label-form">SKU-Induk</p>
|
||||
<TextField
|
||||
hintText=""
|
||||
fullWidth={true}
|
||||
onChange={this.handleReward}
|
||||
/>
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<div className="row">
|
||||
<h2 className='photo-title'>
|
||||
Meta Data
|
||||
</h2>
|
||||
</div>
|
||||
<Divider style={{marginBottom: 20}}/>
|
||||
{!this.state.viewOnly && <div className={"row"}>
|
||||
<FlatButton
|
||||
className="ToolbarGroupLastButton"
|
||||
icon={<AddIcon/>}
|
||||
label="Add Metadata"
|
||||
primary={true}
|
||||
onClick={() => this.addCustomField()}/>
|
||||
</div>}
|
||||
|
||||
{this.state.formData.custom_fields.map((cf, i) => {
|
||||
return (
|
||||
<div key={cf.id} className="row">
|
||||
<div className="col m5 l5">
|
||||
{/* <p className="label-form">Label</p> */}
|
||||
<Input placeholder={`label-${i}`} autosize />
|
||||
{/*<TextField*/}
|
||||
{/*hintText="Label"*/}
|
||||
{/*defaultValue={`label-${i}`}*/}
|
||||
{/*fullWidth={true}*/}
|
||||
{/*onChange={(e,v) => this.changeCustomFieldLabel(i, v)}*/}
|
||||
{/*/>*/}
|
||||
</div>
|
||||
<div className="col m5 l5">
|
||||
{/* <p className="label-form">Value</p> */}
|
||||
<Input placeholder={`Value`} autosize />
|
||||
{/*<TextField*/}
|
||||
{/*hintText="Value"*/}
|
||||
{/*fullWidth={true}*/}
|
||||
{/*onChange={(e,v) => this.changeCustomFieldValue(i, v)}*/}
|
||||
{/*/>*/}
|
||||
</div>
|
||||
<div className="col m2 l">
|
||||
{
|
||||
!this.state.viewOnly && <ButtonAntd shape="circle" icon="delete" onClick={()=>this.removeCustomField(i)}/>
|
||||
}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
<div className={"col s5"}>
|
||||
<Card className="animated fadeIn cardLite">
|
||||
<div style={{padding: '14px'}}>
|
||||
<div className="row">
|
||||
<div className="row">
|
||||
<h2 className='photo-title'>
|
||||
Galleries
|
||||
</h2>
|
||||
</div>
|
||||
<Divider style={{marginBottom: 20}}/>
|
||||
<div className="row">
|
||||
<div className="col s12">
|
||||
<Upload
|
||||
listType="picture-card"
|
||||
fileList={fileList}
|
||||
customRequest={(...args) => this.uploaderHandler(...args)}
|
||||
style={{}}
|
||||
onChange={this.handleChange}
|
||||
>
|
||||
{fileList.length >= 9 || this.state.viewOnly ? null : uploadButton}
|
||||
</Upload>
|
||||
<Modal visible={previewVisible} footer={null} onCancel={this.handleCancel}>
|
||||
<img alt="example" style={{ width: '100%' }} src={previewImage} />
|
||||
</Modal>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<div className="row">
|
||||
<h2 className='photo-title'>
|
||||
Stock and Pricing
|
||||
</h2>
|
||||
</div>
|
||||
<Divider style={{marginBottom: 20}}/>
|
||||
<div className="row">
|
||||
<div className="col m6 l6">
|
||||
<p className="label-form">Price</p>
|
||||
<InputGroup compact>
|
||||
<Input style={{ width: '30%' }} defaultValue="Rp. " disabled={true}/>
|
||||
{wrapperText("regular_price")(
|
||||
<NumberFormat thousandSeparator={true} disabled={this.state.viewOnly} style={{ width: '70%', padding: '4px 11px', height: '32px', fontSize: '14px', border: '1px solid #d9d9d9', borderRadius: '4px' }} placeholder="E.g. 50000" />
|
||||
)}
|
||||
</InputGroup>
|
||||
</div>
|
||||
<div className="col m6 l6">
|
||||
<p className="label-form">Stock</p>
|
||||
{wrapperText("stock")(
|
||||
<Input placeholder="E.g. 50" onChange={this.handleMin} disabled={this.state.viewOnly} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<div className="row">
|
||||
<h2 className='photo-title'>
|
||||
Delivery Services
|
||||
</h2>
|
||||
</div>
|
||||
<Divider style={{marginBottom: 20}}/>
|
||||
<div className="row">
|
||||
<div className="col m6 l6">
|
||||
<p className="label-form">Weight</p>
|
||||
<InputGroup compact>
|
||||
{wrapperText("weight")(
|
||||
<Input style={{ width: '65%' }} disabled={this.state.viewOnly} placeholder="E.g. 5" />
|
||||
)}
|
||||
<Input style={{ width: '35%' }} defaultValue="Gram" disabled={true}/>
|
||||
</InputGroup>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{false && (
|
||||
<div className="row">
|
||||
<div className="col m12 l12">
|
||||
<p className="label-form">Shipping Charges</p>
|
||||
<div className='col s8' style={{paddingTop: 15}}>
|
||||
<div className='left-section'>
|
||||
J&T Express (maks 50000gr)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='col s4' style={{paddingTop: 15}}>
|
||||
<div className='right-section'>
|
||||
<div className='row'>
|
||||
<div className='col s9' style={{textAlign: 'left'}}>
|
||||
<p className='text-delivery'>
|
||||
Rp120.000
|
||||
</p>
|
||||
</div>
|
||||
<div className='col s3' style={{textAlign: 'right'}}>
|
||||
<Toggle className='toggle-delivery' />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='col s8' style={{paddingTop: 15}}>
|
||||
<div className='left-section'>
|
||||
JNE REG(maks 50000gr)
|
||||
</div>
|
||||
</div>
|
||||
<div className='col s4' style={{paddingTop: 15}}>
|
||||
<div className='right-section'>
|
||||
<div className='row'>
|
||||
<div className='col s9' style={{textAlign: 'left'}}>
|
||||
<p className='text-delivery'>
|
||||
Rp108.000
|
||||
</p>
|
||||
</div>
|
||||
<div className='col s3' style={{textAlign: 'right'}}>
|
||||
<Toggle className='toggle-delivery' />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='col s8' style={{paddingTop: 15}}>
|
||||
<div className='left-section'>
|
||||
JNE OKE(maks 50000gr)
|
||||
</div>
|
||||
</div>
|
||||
<div className='col s4' style={{paddingTop: 15}}>
|
||||
<div className='right-section'>
|
||||
<div className='row'>
|
||||
<div className='col s9' style={{textAlign: 'left'}}>
|
||||
<p className='text-delivery'>
|
||||
Rp96.000
|
||||
</p>
|
||||
</div>
|
||||
<div className='col s3' style={{textAlign: 'right'}}>
|
||||
<Toggle className='toggle-delivery' />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='col s8' style={{paddingTop: 15}}>
|
||||
<div className='left-section'>
|
||||
Pos Kilat Khusus(maks 50000gr)
|
||||
</div>
|
||||
</div>
|
||||
<div className='col s4' style={{paddingTop: 15}}>
|
||||
<div className='right-section'>
|
||||
<div className='row'>
|
||||
<div className='col s9' style={{textAlign: 'left'}}>
|
||||
<p className='text-delivery'>
|
||||
Rp102.000
|
||||
</p>
|
||||
</div>
|
||||
<div className='col s3' style={{textAlign: 'right'}}>
|
||||
<Toggle className='toggle-delivery' />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{/*<div className="row">*/}
|
||||
{/*<div className='col s12' style={{textAlign: "right"}}>*/}
|
||||
{/*<RaisedButton label="Save" onClick={this.handleOpen} primary={true} style={{marginTop: '2.3em'}}/>*/}
|
||||
{/*</div>*/}
|
||||
{/*</div>*/}
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Dialog
|
||||
title="Warning"
|
||||
actions={actions}
|
||||
modal={true}
|
||||
open={this.state.openedDialog}
|
||||
onRequestClose={() => this.handleClose()}
|
||||
>
|
||||
Make sure all of your data is correct before submitting.
|
||||
</Dialog>
|
||||
<Dialog
|
||||
title="Warning"
|
||||
actions={actionsBack}
|
||||
modal={true}
|
||||
contentStyle={{width: 350}}
|
||||
open={this.state.openedDialogBack}
|
||||
onRequestClose={() => this.handleBackClose()}
|
||||
>
|
||||
Are you sure you wanna go back ?
|
||||
</Dialog>
|
||||
|
||||
<Dialog
|
||||
title="Warning"
|
||||
actions={actionsDelete}
|
||||
modal={true}
|
||||
open={this.state.openDeleteDialog}
|
||||
onRequestClose={() => this.handleWarningDialog(false)}
|
||||
>
|
||||
Are you sure want to delete this item?
|
||||
</Dialog>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
193
src/common/pages/Items/FormItems/Upload.js
Normal file
193
src/common/pages/Items/FormItems/Upload.js
Normal file
@@ -0,0 +1,193 @@
|
||||
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,
|
||||
Tabs, Tab,
|
||||
RaisedButton,
|
||||
Toolbar,
|
||||
DatePicker,
|
||||
FontIcon,
|
||||
Table,
|
||||
TableBody,
|
||||
TableHeader,
|
||||
TableHeaderColumn,
|
||||
TableRow,
|
||||
TableRowColumn,
|
||||
MenuItem,
|
||||
ToolbarGroup,
|
||||
FloatingActionButton,
|
||||
ToolbarSeparator,
|
||||
IconButton,
|
||||
ToolbarTitle,
|
||||
RadioButton,
|
||||
TextField,
|
||||
Paper,
|
||||
RadioButtonGroup,
|
||||
Dialog,
|
||||
SelectField,
|
||||
GridList,
|
||||
GridTile,
|
||||
Toggle
|
||||
} from 'material-ui';
|
||||
import StarBorder from 'material-ui/svg-icons/toggle/star-border';
|
||||
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 { Upload, Icon, Modal, message, } from 'antd';
|
||||
import '../style.scss';
|
||||
import {appConfig} from "../../../config/app";
|
||||
import {Link} from 'react-router-dom';
|
||||
import {LINKS} from "../../../routes";
|
||||
import uuid from 'uuid';
|
||||
|
||||
let DateTimeFormat = global.Intl.DateTimeFormat;
|
||||
const Dragger = Upload.Dragger;
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class Uploads extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.rewardStore = props.appstate.reward;
|
||||
this.state = {
|
||||
openedDialog: false,
|
||||
value: 1,
|
||||
searchText: '',
|
||||
slideIndex: 0,
|
||||
openedDialogBack: false,
|
||||
reward_type: "Choose Reward Type",
|
||||
expanded: false,
|
||||
previewVisible: false,
|
||||
previewImage: '',
|
||||
fileList: [],
|
||||
formData: {
|
||||
custom_fields: []
|
||||
}
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
|
||||
this.http = props.appstate.http;
|
||||
this.authStore = props.appstate.auth;
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
this.categoryStore = props.appstate.category;
|
||||
this.itemStore = props.appstate.item;
|
||||
this.userData = props.appstate.userData;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.itemStore.listImages = [];
|
||||
console.log(this.props.id,'ini id dari detail');
|
||||
}
|
||||
|
||||
handleChange = ({ fileList }) => this.setState({ fileList });
|
||||
|
||||
uploaderHandler = (file) => {
|
||||
this.http.upload(file)
|
||||
.then(async res => {
|
||||
const {fileList} = this.state;
|
||||
fileList.push({
|
||||
uid: fileList.length + 1,
|
||||
name: file.name,
|
||||
status: 'done',
|
||||
url: this.http.appendImagePath(res.path),
|
||||
path: res.path
|
||||
});
|
||||
await this.itemStore.addImages(fileList[0]);
|
||||
await console.log(this.itemStore.listImages.slice(), 'store');
|
||||
if(this.userData.role === 'administrator') {
|
||||
this.props.history.push(`${LINKS.FORM_ITEMS}/${this.props.id}`);
|
||||
}
|
||||
else if(this.userData.role === 'store'){
|
||||
this.props.history.push(LINKS.FORM_ITEMS);
|
||||
}
|
||||
// this.setState({fileList});
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
|
||||
const { previewVisible, previewImage, fileList } = this.state;
|
||||
const props = {
|
||||
name: 'file',
|
||||
multiple: false,
|
||||
action: `${appConfig.apiUrl}files/`,
|
||||
onChange: async (info) => {
|
||||
const status = info.file.status;
|
||||
if (status === 'done') {
|
||||
await this.uploaderHandler(info.file.originFileObj);
|
||||
} else if (status === 'error') {
|
||||
message.error(`${info.file.name} file upload failed.`);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
<div style={{marginTop: 35}}>
|
||||
<div className="row">
|
||||
<div className="col l12 m12 s12">
|
||||
<Card className="animated fadeIn cardLite">
|
||||
<Toolbar className="toolbarCard" style={{backgroundColor: '#fff'}}>
|
||||
<ToolbarGroup>
|
||||
<IconButton
|
||||
iconClassName="material-icons"
|
||||
tooltip="Back"
|
||||
style={{marginLeft: '-10px'}}
|
||||
onClick={() => this.props.history.goBack()}
|
||||
>
|
||||
arrow_back
|
||||
</IconButton>
|
||||
<ToolbarTitle style={{fontSize: 14, fontWeight: 500, color: '#32325d'}} text={'Add New Item'}/>
|
||||
</ToolbarGroup>
|
||||
</Toolbar>
|
||||
<Divider/>
|
||||
<div style={{padding: '14px'}}>
|
||||
<div className="row">
|
||||
<div className="row">
|
||||
<h2 className='photo-title'>
|
||||
Let's start with adding some of your item's photo
|
||||
</h2>
|
||||
</div>
|
||||
<div className="row">
|
||||
{/*<div className="">*/}
|
||||
{/*<Upload*/}
|
||||
{/*listType="picture-card"*/}
|
||||
{/*fileList={fileList}*/}
|
||||
{/*customRequest={(...args) => this.uploaderHandler(...args)}*/}
|
||||
{/*style={{}}*/}
|
||||
{/*>*/}
|
||||
{/*{fileList.length >= 9 ? null : uploadButton}*/}
|
||||
{/*</Upload>*/}
|
||||
{/*<Modal visible={previewVisible} footer={null} onCancel={this.handleCancel}>*/}
|
||||
{/*<img alt="example" style={{ width: '100%' }} src={previewImage} />*/}
|
||||
{/*</Modal>*/}
|
||||
{/*</div>*/}
|
||||
<div className="col s12 box-upload">
|
||||
<Dragger {...props}>
|
||||
<p className="ant-upload-drag-icon">
|
||||
<Icon type="inbox" />
|
||||
</p>
|
||||
<p className="ant-upload-text">Click or drag file to this area to upload</p>
|
||||
<p className="ant-upload-hint">Support for a single upload. Max 9 of picture and 2.0 MB size per picture, picture format only</p>
|
||||
</Dragger>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
87
src/common/pages/Items/FormItems/UploadAdmin.js
Normal file
87
src/common/pages/Items/FormItems/UploadAdmin.js
Normal file
@@ -0,0 +1,87 @@
|
||||
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 ImageEdit from 'material-ui/svg-icons/image/edit';
|
||||
import EmptyComponent from '../../EmptyComponent';
|
||||
import LoadingDialog from "../../LoadingDialog";
|
||||
import Loader from 'react-loader-advanced';
|
||||
import {appConfig} from "../../../config/app";
|
||||
import {Link} from 'react-router-dom';
|
||||
import {LINKS} from "../../../routes";
|
||||
import moment from 'moment';
|
||||
import {DIALOG} from "../../../stores/global_ui";
|
||||
import Uploads from './Upload';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class UploadAdminDetail extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
value: 0,
|
||||
edit : false,
|
||||
defaultValue : {}
|
||||
};
|
||||
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.storeListStore = props.appstate.storeList;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
console.log('ini detail upload',this.props.match.params.id)
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
<Uploads id={this.props.match.params.id} history={this.props.history}/>
|
||||
)
|
||||
}
|
||||
}
|
||||
190
src/common/pages/Items/FormItems/UploadPromotion.js
Normal file
190
src/common/pages/Items/FormItems/UploadPromotion.js
Normal file
@@ -0,0 +1,190 @@
|
||||
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,
|
||||
Tabs, Tab,
|
||||
RaisedButton,
|
||||
Toolbar,
|
||||
DatePicker,
|
||||
FontIcon,
|
||||
Table,
|
||||
TableBody,
|
||||
TableHeader,
|
||||
TableHeaderColumn,
|
||||
TableRow,
|
||||
TableRowColumn,
|
||||
MenuItem,
|
||||
ToolbarGroup,
|
||||
FloatingActionButton,
|
||||
ToolbarSeparator,
|
||||
IconButton,
|
||||
ToolbarTitle,
|
||||
RadioButton,
|
||||
TextField,
|
||||
Paper,
|
||||
RadioButtonGroup,
|
||||
Dialog,
|
||||
SelectField,
|
||||
GridList,
|
||||
GridTile,
|
||||
Toggle
|
||||
} from 'material-ui';
|
||||
import StarBorder from 'material-ui/svg-icons/toggle/star-border';
|
||||
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 { Upload, Icon, Modal, message, } from 'antd';
|
||||
import '../style.scss';
|
||||
import {appConfig} from "../../../config/app";
|
||||
import {Link} from 'react-router-dom';
|
||||
import {LINKS} from "../../../routes";
|
||||
import uuid from 'uuid';
|
||||
|
||||
let DateTimeFormat = global.Intl.DateTimeFormat;
|
||||
const Dragger = Upload.Dragger;
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class UploadPromotion extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.rewardStore = props.appstate.reward;
|
||||
this.state = {
|
||||
openedDialog: false,
|
||||
value: 1,
|
||||
searchText: '',
|
||||
slideIndex: 0,
|
||||
openedDialogBack: false,
|
||||
reward_type: "Choose Reward Type",
|
||||
expanded: false,
|
||||
previewVisible: false,
|
||||
previewImage: '',
|
||||
fileList: [],
|
||||
formData: {
|
||||
custom_fields: []
|
||||
}
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
|
||||
this.http = props.appstate.http;
|
||||
this.authStore = props.appstate.auth;
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
this.categoryStore = props.appstate.category;
|
||||
this.itemStore = props.appstate.item;
|
||||
this.userData = props.appstate.userData;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.itemStore.listImages = [];
|
||||
console.log(this.props.id,'ini id dari detail');
|
||||
}
|
||||
|
||||
handleChange = ({ fileList }) => this.setState({ fileList });
|
||||
|
||||
uploaderHandler = (file) => {
|
||||
this.http.upload(file)
|
||||
.then(async res => {
|
||||
const {fileList} = this.state;
|
||||
fileList.push({
|
||||
uid: fileList.length + 1,
|
||||
name: file.name,
|
||||
status: 'done',
|
||||
url: this.http.appendImagePath(res.path),
|
||||
path: res.path
|
||||
});
|
||||
await this.itemStore.addImages(fileList[0]);
|
||||
await console.log(this.itemStore.listImages.slice(), 'store');
|
||||
if(this.userData.role === 'administrator') {
|
||||
this.props.history.push(`${LINKS.FORM_PROMOTION}`);
|
||||
}
|
||||
// this.setState({fileList});
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
|
||||
const { previewVisible, previewImage, fileList } = this.state;
|
||||
const props = {
|
||||
name: 'file',
|
||||
multiple: false,
|
||||
action: `${appConfig.apiUrl}files/`,
|
||||
onChange: async (info) => {
|
||||
const status = info.file.status;
|
||||
if (status === 'done') {
|
||||
await this.uploaderHandler(info.file.originFileObj);
|
||||
} else if (status === 'error') {
|
||||
message.error(`${info.file.name} file upload failed.`);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
<div style={{marginTop: 35}}>
|
||||
<div className="row">
|
||||
<div className="col l12 m12 s12">
|
||||
<Card className="animated fadeIn cardLite">
|
||||
<Toolbar className="toolbarCard" style={{backgroundColor: '#fff'}}>
|
||||
<ToolbarGroup>
|
||||
<IconButton
|
||||
iconClassName="material-icons"
|
||||
tooltip="Back"
|
||||
style={{marginLeft: '-10px'}}
|
||||
onClick={() => this.props.history.goBack()}
|
||||
>
|
||||
arrow_back
|
||||
</IconButton>
|
||||
<ToolbarTitle style={{fontSize: 14, fontWeight: 500, color: '#32325d'}} text={'Add New Item'}/>
|
||||
</ToolbarGroup>
|
||||
</Toolbar>
|
||||
<Divider/>
|
||||
<div style={{padding: '14px'}}>
|
||||
<div className="row">
|
||||
<div className="row">
|
||||
<h2 className='photo-title'>
|
||||
Let's start with adding some of your item's photo
|
||||
</h2>
|
||||
</div>
|
||||
<div className="row">
|
||||
{/*<div className="">*/}
|
||||
{/*<Upload*/}
|
||||
{/*listType="picture-card"*/}
|
||||
{/*fileList={fileList}*/}
|
||||
{/*customRequest={(...args) => this.uploaderHandler(...args)}*/}
|
||||
{/*style={{}}*/}
|
||||
{/*>*/}
|
||||
{/*{fileList.length >= 9 ? null : uploadButton}*/}
|
||||
{/*</Upload>*/}
|
||||
{/*<Modal visible={previewVisible} footer={null} onCancel={this.handleCancel}>*/}
|
||||
{/*<img alt="example" style={{ width: '100%' }} src={previewImage} />*/}
|
||||
{/*</Modal>*/}
|
||||
{/*</div>*/}
|
||||
<div className="col s12 box-upload">
|
||||
<Dragger {...props}>
|
||||
<p className="ant-upload-drag-icon">
|
||||
<Icon type="inbox" />
|
||||
</p>
|
||||
<p className="ant-upload-text">Click or drag file to this area to upload</p>
|
||||
<p className="ant-upload-hint">Support for a single upload. Max 9 of picture and 2.0 MB size per picture, picture format only</p>
|
||||
</Dragger>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
96
src/common/pages/Items/ItemCard/index.js
Normal file
96
src/common/pages/Items/ItemCard/index.js
Normal file
@@ -0,0 +1,96 @@
|
||||
import React from 'react';
|
||||
import {inject, observer} from 'mobx-react';
|
||||
import {
|
||||
Card,
|
||||
CardMedia,
|
||||
CardTitle,
|
||||
CardText,
|
||||
FontIcon,
|
||||
} from 'material-ui';
|
||||
import NumberFormat from 'react-number-format';
|
||||
import {Link} from 'react-router-dom';
|
||||
import {LINKS} from "../../../routes";
|
||||
import {appConfig} from "../../../config/app";
|
||||
import get from 'lodash.get';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export class ItemCard extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
|
||||
this.http = props.appstate.http;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// console.log('ItemCard');
|
||||
}
|
||||
|
||||
render() {
|
||||
const {data = {}} = this.props;
|
||||
const main = get(data,'images.main',null)
|
||||
const mainImage = this.http.appendImagePath(main);
|
||||
|
||||
return (
|
||||
<Link to={`${LINKS.FORM_ITEMS}/edit/${data.id}`}>
|
||||
<Card className="animated fadeIn cardLite marketplace-cardBox" style={{height: 323, cursor: 'pointer', textOverflow: 'ellipsis'}}>
|
||||
<CardMedia>
|
||||
<img src={(main) ? mainImage : 'https://marketplace-sillyfish-api.asacreative.com/assets/no-image.png'} alt="" style={{height: 175, objectFit: 'cover'}}/>
|
||||
</CardMedia>
|
||||
{/*<CardTitle style={{padding:8}} subtitleStyle={{display:'none'}} title={data.name} titleStyle={{fontSize: 12}}/>*/}
|
||||
|
||||
<CardTitle title={<Link to={`${LINKS.FORM_ITEMS}/${data.id}`}>{(data.name.length > 14) ? data.name.substring(0,13)+`...` : data.name}</Link>} titleStyle={{fontWeight: 'bold', fontSize: 18, lineHeight: '30px', whiteSpace: 'nowrap'}}
|
||||
subtitle={<NumberFormat style={{fontWeight: 'bold', color: 'orangered'}}
|
||||
value={data.regular_price}
|
||||
displayType={'text'}
|
||||
thousandSeparator={true} prefix={'Rp'}/>}/>
|
||||
|
||||
{/*<CardText style={{padding: 8}}>*/}
|
||||
{/*<p className="font-14" style={{marginBottom: 32, fontWeight: 'bold'}}>{data.name}</p>*/}
|
||||
{/*<div className="flex flexSpaceBetween">*/}
|
||||
{/*<NumberFormat style={{fontWeight: 'bold', color: 'orangered'}} value={data.regular_price}*/}
|
||||
{/*displayType={'text'}*/}
|
||||
{/*thousandSeparator={true} prefix={'Rp'}/>*/}
|
||||
{/*<div style={{fontSize: "11px"}}><span style={{color: '#5a637e7d'}}>Stock</span>{data.stock}</div>*/}
|
||||
{/*</div>*/}
|
||||
{/*</CardText>*/}
|
||||
|
||||
<CardText style={{
|
||||
padding: '16px 16px 8px',
|
||||
boxShadow: '0px 5px 15px rgba(0,0,0,0.05)',
|
||||
borderRadius: 6,
|
||||
fontSize: 12
|
||||
}}>
|
||||
<div><span style={{color: '#636c72', fontWeight: '300'}}>Stock :</span> {+data.stock} {data.uom}</div>
|
||||
</CardText>
|
||||
|
||||
<CardText style={{padding: "4px 16px"}}>
|
||||
<div className="flex flexSpaceBetween">
|
||||
<div className="font-12" style={{fontSize: '.72rem'}}>
|
||||
<FontIcon className="material-icons font-12"
|
||||
color='#636c72'
|
||||
style={{
|
||||
display: "inlineFlex", verticalAlign: "middle", lineHight: 1
|
||||
}}>remove_red_eye</FontIcon> : {data.seen}
|
||||
</div>
|
||||
<div className="" style={{fontSize: '.72rem'}}>
|
||||
<FontIcon className="material-icons font-12" color='#636c72' style={{
|
||||
display: "inlineFlex",
|
||||
verticalAlign: "middle",
|
||||
lineHight: 1,
|
||||
}}>favorite_border</FontIcon> : {data.wishlist}
|
||||
</div>
|
||||
<div style={{fontSize: '.72rem'}}><span style={{color: '#636c72', fontWeight: '300'}}>Sold</span>
|
||||
: {data.sold}</div>
|
||||
</div>
|
||||
</CardText>
|
||||
|
||||
</Card>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
229
src/common/pages/Items/SoldOut/index.js
Normal file
229
src/common/pages/Items/SoldOut/index.js
Normal file
@@ -0,0 +1,229 @@
|
||||
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
|
||||
} 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 EyeIcon from 'material-ui/svg-icons/image/remove-red-eye';
|
||||
import DeleteIcon from 'material-ui/svg-icons/content/delete-sweep';
|
||||
import ImageEdit from 'material-ui/svg-icons/image/edit';
|
||||
import EmptyComponent from '../../EmptyComponent';
|
||||
import LoadingDialog from "../../LoadingDialog";
|
||||
import Loader from 'react-loader-advanced';
|
||||
import {Row, Col} from 'antd';
|
||||
|
||||
import '../style.scss';
|
||||
import {appConfig} from "../../../config/app";
|
||||
import {Link} from 'react-router-dom';
|
||||
import {LINKS} from "../../../routes";
|
||||
import {ItemCard} from '../ItemCard';
|
||||
import InfiniteScroll from 'react-infinite-scroller';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class SoldOut extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
value: 0,
|
||||
statusBanned: "Banned",
|
||||
statusSoldOut: "Sold Out"
|
||||
};
|
||||
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.rewardStore = props.appstate.reward;
|
||||
|
||||
this.myStoreItem = props.appstate.myStoreItem;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// this.myStoreItem.isSearching = false;
|
||||
// this.myStoreItem.setRequestQuery({status : 'sold_out'});
|
||||
this.myStoreItem.getAll();
|
||||
this.myStoreItem.setRequestQuery({visible : true});
|
||||
}
|
||||
|
||||
componentWillUnmount(){
|
||||
this.myStoreItem.isSearching = false;
|
||||
this.myStoreItem.reset();
|
||||
}
|
||||
|
||||
search = (event)=>{
|
||||
console.log("dataSearch",event.target.value);
|
||||
if(event.target.value.length == 0){
|
||||
this.myStoreItem.isSearching = false;
|
||||
}
|
||||
else{
|
||||
this.myStoreItem.isSearching = true;
|
||||
this.myStoreItem.search(event.target.value);
|
||||
}
|
||||
}
|
||||
|
||||
deleteClicked = (id) => {
|
||||
this.state.id = id;
|
||||
this.setState({
|
||||
openedDelete: true
|
||||
});
|
||||
}
|
||||
|
||||
handleClickDelete = (id) => {
|
||||
this.rewardStore.deleteReward(id);
|
||||
this.setState({
|
||||
openedDelete: false,
|
||||
openSnackbarDelete: true
|
||||
});
|
||||
this.globalUI.openSnackbar("Successful Deleted Existing Reward");
|
||||
}
|
||||
|
||||
handleCloseDelete = () => {
|
||||
this.setState({
|
||||
openedDelete: false
|
||||
})
|
||||
}
|
||||
|
||||
handleChange = (event, index, value) => this.setState({value});
|
||||
|
||||
loadMore = ()=>{
|
||||
console.log('RUNNss');
|
||||
if(this.myStoreItem.data.length > 0){
|
||||
this.myStoreItem.nextPage(true);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
console.log(this.myStoreItem.data.length);
|
||||
|
||||
const actionsDelete = [
|
||||
<FlatButton
|
||||
label="Cancel"
|
||||
primary={true}
|
||||
onClick={this.handleCloseDelete}
|
||||
/>,
|
||||
<FlatButton
|
||||
label="Delete"
|
||||
primary={true}
|
||||
onClick={() => this.handleClickDelete(this.state.id)}
|
||||
/>,
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="row">
|
||||
<div className="col l12 m12 s12">
|
||||
<Card className="animated fadeIn cardLite">
|
||||
<Toolbar className="toolbarCard radius4" style={{backgroundColor: '#fff'}}>
|
||||
<ToolbarGroup>
|
||||
<SearchIcon style={{marginRight: 8, color: "#999"}}/>
|
||||
<TextField
|
||||
hintText="Search SoldOut By Name"
|
||||
style={{fontSize: 14}}
|
||||
hintStyle={{fontSize: 14}}
|
||||
underlineShow={false}
|
||||
onChange={this.search}
|
||||
/>
|
||||
</ToolbarGroup>
|
||||
{/*<ToolbarGroup className="ToolbarGroupLast">*/}
|
||||
{/*<ToolbarSeparator/>*/}
|
||||
{/*<Link to={`${LINKS.FORM_ITEMS}`}>*/}
|
||||
{/*<RaisedButton className="ToolbarGroupLastButton" icon={<AddIcon/>} label="New Items"*/}
|
||||
{/*primary={true}/>*/}
|
||||
{/*</Link>*/}
|
||||
{/*</ToolbarGroup>*/}
|
||||
</Toolbar>
|
||||
|
||||
{/*<div style={{paddingBottom: 5}}>*/}
|
||||
{/*<Loader show={false} message={<LoadingDialog/>}*/}
|
||||
{/*messageStyle={{textAlign: 'center'}} backgroundStyle={{backgroundColor: 'rgba(255,255,255,0.5)'}}>*/}
|
||||
|
||||
{/*</Loader>*/}
|
||||
{/*</div>*/}
|
||||
<Dialog
|
||||
title="Warning"
|
||||
actions={actionsDelete}
|
||||
modal={true}
|
||||
open={this.state.openedDelete}
|
||||
onRequestClose={() => this.handleCloseDelete()}
|
||||
>
|
||||
Are you sure want to delete this data?
|
||||
</Dialog>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InfiniteScroll pageStart={0} loadMore={this.loadMore} hasMore={true}>
|
||||
<Row className="row rowItem" gutter={8}>
|
||||
{/*<Col className="gutter-row col animated fadeIn" span={4}>
|
||||
<Link to={`${LINKS.FORM_UPLOAD}`} style={{color:'#424770'}}>
|
||||
<div className="flex add-new"
|
||||
style={{
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
height: 323
|
||||
}}>
|
||||
<div>
|
||||
<FontIcon className="material-icons icon-add ">add</FontIcon>
|
||||
</div>
|
||||
Add new item
|
||||
</div>
|
||||
</Link>
|
||||
</Col>*/}
|
||||
{(this.myStoreItem.isSearching ? this.myStoreItem.dataFiltered : this.myStoreItem.data).filter(f=>f.stock == 0).map(item => {
|
||||
return (<Col key={item.id} className="gutter-row col" span={4} style={{marginBottom: 20}}>
|
||||
<div className="gutter-box"><ItemCard data={item}/></div>
|
||||
</Col>)
|
||||
})}
|
||||
</Row>
|
||||
</InfiniteScroll>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
228
src/common/pages/Items/Unactive/index.js
Normal file
228
src/common/pages/Items/Unactive/index.js
Normal file
@@ -0,0 +1,228 @@
|
||||
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
|
||||
} 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 EyeIcon from 'material-ui/svg-icons/image/remove-red-eye';
|
||||
import DeleteIcon from 'material-ui/svg-icons/content/delete-sweep';
|
||||
import ImageEdit from 'material-ui/svg-icons/image/edit';
|
||||
import EmptyComponent from '../../EmptyComponent';
|
||||
import LoadingDialog from "../../LoadingDialog";
|
||||
import Loader from 'react-loader-advanced';
|
||||
import {Row, Col} from 'antd';
|
||||
|
||||
import '../style.scss';
|
||||
import {appConfig} from "../../../config/app";
|
||||
import {Link} from 'react-router-dom';
|
||||
import {LINKS} from "../../../routes";
|
||||
import {ItemCard} from '../ItemCard';
|
||||
import InfiniteScroll from 'react-infinite-scroller';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class Unactive extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
value: 0,
|
||||
statusBanned: "Banned",
|
||||
statusSoldOut: "Sold Out"
|
||||
};
|
||||
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.rewardStore = props.appstate.reward;
|
||||
|
||||
this.myStoreItem = props.appstate.myStoreItem;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// this.myStoreItem.isSearching = false;
|
||||
this.myStoreItem.setRequestQuery({visible : false});
|
||||
this.myStoreItem.getAll();
|
||||
}
|
||||
|
||||
componentWillUnmount(){
|
||||
this.myStoreItem.isSearching = false;
|
||||
this.myStoreItem.reset();
|
||||
}
|
||||
|
||||
deleteClicked = (id) => {
|
||||
this.state.id = id;
|
||||
this.setState({
|
||||
openedDelete: true
|
||||
});
|
||||
}
|
||||
|
||||
search = (event)=>{
|
||||
console.log("dataSearch",event.target.value);
|
||||
if(event.target.value.length == 0){
|
||||
this.myStoreItem.isSearching = false;
|
||||
}
|
||||
else{
|
||||
this.myStoreItem.isSearching = true;
|
||||
this.myStoreItem.search(event.target.value);
|
||||
}
|
||||
}
|
||||
|
||||
handleClickDelete = (id) => {
|
||||
this.rewardStore.deleteReward(id);
|
||||
this.setState({
|
||||
openedDelete: false,
|
||||
openSnackbarDelete: true
|
||||
});
|
||||
this.globalUI.openSnackbar("Successful Deleted Existing Reward");
|
||||
}
|
||||
|
||||
handleCloseDelete = () => {
|
||||
this.setState({
|
||||
openedDelete: false
|
||||
})
|
||||
}
|
||||
|
||||
handleChange = (event, index, value) => this.setState({value});
|
||||
|
||||
loadMore = ()=>{
|
||||
console.log('RUNNss');
|
||||
if(this.myStoreItem.data.length > 0){
|
||||
this.myStoreItem.nextPage(true);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
console.log(this.myStoreItem.data.length);
|
||||
|
||||
const actionsDelete = [
|
||||
<FlatButton
|
||||
label="Cancel"
|
||||
primary={true}
|
||||
onClick={this.handleCloseDelete}
|
||||
/>,
|
||||
<FlatButton
|
||||
label="Delete"
|
||||
primary={true}
|
||||
onClick={() => this.handleClickDelete(this.state.id)}
|
||||
/>,
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="row">
|
||||
<div className="col l12 m12 s12">
|
||||
<Card className="animated fadeIn cardLite">
|
||||
<Toolbar className="toolbarCard radius4" style={{backgroundColor: '#fff'}}>
|
||||
<ToolbarGroup>
|
||||
<SearchIcon style={{marginRight: 8, color: "#999"}}/>
|
||||
<TextField
|
||||
hintText="Search Unactive By Name"
|
||||
style={{fontSize: 14}}
|
||||
hintStyle={{fontSize: 14}}
|
||||
underlineShow={false}
|
||||
onChange={this.search}
|
||||
/>
|
||||
</ToolbarGroup>
|
||||
{/*<ToolbarGroup className="ToolbarGroupLast">*/}
|
||||
{/*<ToolbarSeparator/>*/}
|
||||
{/*<Link to={`${LINKS.FORM_ITEMS}`}>*/}
|
||||
{/*<RaisedButton className="ToolbarGroupLastButton" icon={<AddIcon/>} label="New Items"*/}
|
||||
{/*primary={true}/>*/}
|
||||
{/*</Link>*/}
|
||||
{/*</ToolbarGroup>*/}
|
||||
</Toolbar>
|
||||
|
||||
{/*<div style={{paddingBottom: 5}}>*/}
|
||||
{/*<Loader show={false} message={<LoadingDialog/>}*/}
|
||||
{/*messageStyle={{textAlign: 'center'}} backgroundStyle={{backgroundColor: 'rgba(255,255,255,0.5)'}}>*/}
|
||||
|
||||
{/*</Loader>*/}
|
||||
{/*</div>*/}
|
||||
<Dialog
|
||||
title="Warning"
|
||||
actions={actionsDelete}
|
||||
modal={true}
|
||||
open={this.state.openedDelete}
|
||||
onRequestClose={() => this.handleCloseDelete()}
|
||||
>
|
||||
Are you sure want to delete this data?
|
||||
</Dialog>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InfiniteScroll pageStart={0} loadMore={this.loadMore} hasMore={true}>
|
||||
<Row className="row rowItem" gutter={8}>
|
||||
{/*<Col className="gutter-row col animated fadeIn" span={4}>
|
||||
<Link to={`${LINKS.FORM_UPLOAD}`} style={{color:'#424770'}}>
|
||||
<div className="flex add-new"
|
||||
style={{
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
height: 323
|
||||
}}>
|
||||
<div>
|
||||
<FontIcon className="material-icons icon-add ">add</FontIcon>
|
||||
</div>
|
||||
Add new item
|
||||
</div>
|
||||
</Link>
|
||||
</Col>*/}
|
||||
{(this.myStoreItem.isSearching ? this.myStoreItem.dataFiltered : this.myStoreItem.data).map(item => {
|
||||
return (<Col key={item.id} className="gutter-row col" span={4} style={{marginBottom: 20}}>
|
||||
<div className="gutter-box"><ItemCard data={item}/></div>
|
||||
</Col>)
|
||||
})}
|
||||
</Row>
|
||||
</InfiniteScroll>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
98
src/common/pages/Items/index.js
Normal file
98
src/common/pages/Items/index.js
Normal file
@@ -0,0 +1,98 @@
|
||||
import React from 'react';
|
||||
import {inject, observer} from 'mobx-react';
|
||||
import {Link} from 'react-router';
|
||||
import {Tab, Tabs} from 'material-ui';
|
||||
import './style.scss';
|
||||
import All from "./All/index";
|
||||
import Active from "./Active/index";
|
||||
import Unactive from "./Unactive/index";
|
||||
import SoldOut from "./SoldOut/index";
|
||||
import Banned from "./Banned/index";
|
||||
|
||||
export const ITEM_TABS = {
|
||||
ALL: 'all',
|
||||
ACTIVE: 'active',
|
||||
UNACTIVE : 'unactive',
|
||||
SOLD_OUT: 'sold_out',
|
||||
BANNED: 'banned',
|
||||
};
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class ItemsComponent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
tabSelected: 'all',
|
||||
};
|
||||
this.handleChange = this.handleChange.bind(this);
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.http = props.appstate.http;
|
||||
this.authStore = props.appstate.auth;
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
this.appStore = props.appstate.app;
|
||||
this.myStore = props.appstate.myStore;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
}
|
||||
|
||||
handleChange = (tabSelected) => {
|
||||
this.setState({tabSelected: tabSelected});
|
||||
this.globalUI.itemsTabSelected = tabSelected;
|
||||
};
|
||||
|
||||
getContent() {
|
||||
switch (this.globalUI.itemsTabSelected) {
|
||||
case ITEM_TABS.ALL:
|
||||
return <All/>;
|
||||
case ITEM_TABS.ACTIVE:
|
||||
return <Active/>;
|
||||
case ITEM_TABS.UNACTIVE:
|
||||
return <Unactive/>;
|
||||
case ITEM_TABS.SOLD_OUT:
|
||||
return <SoldOut/>;
|
||||
case ITEM_TABS.BANNED:
|
||||
return <Banned/>;
|
||||
default:
|
||||
return <All/>
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const {type:appType} = this.appStore;
|
||||
|
||||
return (
|
||||
<div className="setting containerMiddle">
|
||||
<div className="row">
|
||||
<div className="col l12 m12 s12 no-padding">
|
||||
<Tabs
|
||||
value={this.globalUI.itemsTabSelected}
|
||||
onChange={this.handleChange}
|
||||
inkBarStyle={{background: 'transparent'}}
|
||||
className="tabsAkun"
|
||||
style={{background: 'transparent'}} >
|
||||
<Tab label="All" value="all" className={(this.globalUI.itemsTabSelected === 'all') ? "buttonTabs buttonTabsActive" : 'buttonTabs'}>
|
||||
</Tab>
|
||||
<Tab label="Active" value="active" className={(this.globalUI.itemsTabSelected === 'active') ? "buttonTabs buttonTabsActive" : 'buttonTabs'}>
|
||||
|
||||
</Tab>
|
||||
{/*<Tab label="Inactive" value="unactive" className={(this.globalUI.itemsTabSelected === 'unactive') ? "buttonTabs buttonTabsActive" : 'buttonTabs'}>
|
||||
|
||||
</Tab>*/}
|
||||
<Tab label="Sold Out" value="sold_out" className={(this.globalUI.itemsTabSelected === 'sold_out') ? "buttonTabs buttonTabsActive" : 'buttonTabs'}>
|
||||
|
||||
</Tab>
|
||||
{/*<Tab label="Banned" value="banned" className={(this.globalUI.itemsTabSelected === 'banned') ? "buttonTabs buttonTabsActive" : 'buttonTabs'}>*/}
|
||||
{/**/}
|
||||
{/*</Tab>*/}
|
||||
</Tabs>
|
||||
{this.getContent()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
66
src/common/pages/Items/style.scss
Normal file
66
src/common/pages/Items/style.scss
Normal file
@@ -0,0 +1,66 @@
|
||||
.setting {
|
||||
margin-top: 35px;
|
||||
.container {
|
||||
padding: 25px;
|
||||
|
||||
.ant-card {
|
||||
background: #fff;
|
||||
border-radius: 0;
|
||||
font-size: 12px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition: all .3s;
|
||||
}
|
||||
.ant-card-head {
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
background: #fff;
|
||||
border-bottom: 0 solid #e9e9e9;
|
||||
padding: 0 24px;
|
||||
}
|
||||
.ant-card:hover {
|
||||
box-shadow: 4px 4px 40px rgba(0, 0, 0, .05);
|
||||
border-color: transparent;
|
||||
}
|
||||
.ant-card-body-dashboard {
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.label-form {
|
||||
font-size: 14px;
|
||||
line-height: 30px;
|
||||
color: rgb(153, 153, 153);
|
||||
text-shadow: rgb(255, 255, 255) 0px 1px 0px;
|
||||
margin-bottom: -8px;
|
||||
}
|
||||
|
||||
.backgroundImage {
|
||||
height: 182px;
|
||||
background-image: url('/assets/images/material3.jpg');
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
cursor: pointer;
|
||||
min-height: 75px;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.photo-title{
|
||||
font-size: 1.25em;
|
||||
font-weight: 400;
|
||||
margin-left: 12px;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.box-upload{
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
103
src/common/pages/Layout/index.js
Normal file
103
src/common/pages/Layout/index.js
Normal file
@@ -0,0 +1,103 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import {
|
||||
Tabs, Tab,
|
||||
} from 'material-ui';
|
||||
import {LINKS} from "../../routes";
|
||||
import '../Inbox/style.scss';
|
||||
import FeaturedCat from '../FeaturedCategory';
|
||||
import FeaturedStores from '../FeaturedStores';
|
||||
import FeaturedItems from '../FeaturedItems';
|
||||
import CustomMenu from '../CustomMenus';
|
||||
|
||||
export const TABS_LIST = {
|
||||
BANNER : 'banner',
|
||||
CUSTOM_MENU : 'menu',
|
||||
FEATURED_CATEGORIES: 'featured_categories',
|
||||
FEATURED_STORES: 'featured_stores',
|
||||
};
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class LayoutTabComponent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.taskStore = props.appstate.task;
|
||||
this.state = {
|
||||
tabSelected: TABS_LIST.BANNER,
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.http = props.appstate.http;
|
||||
this.authStore = props.appstate.auth;
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
this.messageStore = props.appstate.message;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// this.props.history.push(LINKS.INBOX +`/${this.messageStore.selectedTab}`)
|
||||
let activeTab = (this.globalUI.layoutTabSelected ? this.globalUI.layoutTabSelected : TABS_LIST.BANNER);
|
||||
this.setState({
|
||||
tabSelected : activeTab
|
||||
});
|
||||
this.props.history.push(LINKS.LAYOUT +`/${activeTab}`)
|
||||
}
|
||||
|
||||
handleChange = (tabSelected) => {
|
||||
this.setState({
|
||||
tabSelected: tabSelected,
|
||||
});
|
||||
this.globalUI.layoutTabSelected = tabSelected;
|
||||
this.props.history.push(LINKS.LAYOUT+'/'+tabSelected);
|
||||
};
|
||||
|
||||
getContent() {
|
||||
switch (this.state.tabSelected) {
|
||||
case TABS_LIST.BANNER:
|
||||
return <FeaturedItems/>
|
||||
case TABS_LIST.CUSTOM_MENU:
|
||||
return <CustomMenu/>
|
||||
case TABS_LIST.FEATURED_STORES:
|
||||
return <FeaturedStores/>
|
||||
case TABS_LIST.FEATURED_CATEGORIES:
|
||||
return <FeaturedCat/>
|
||||
default:
|
||||
return <FeaturedItems/>
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
<div className="inbox containerMiddle">
|
||||
<div className="row no-margin">
|
||||
<div className="col l12 m12 s12">
|
||||
<Tabs
|
||||
value={this.state.tabSelected}
|
||||
onChange={this.handleChange}
|
||||
inkBarStyle={{background: 'transparent'}}
|
||||
className="tabsAkun"
|
||||
style={{background: 'transparent'}}
|
||||
>
|
||||
<Tab label="Banner" value="banner"
|
||||
className={(this.state.tabSelected === 'banner') ? "buttonTabs buttonTabsActive" : 'buttonTabs'}>
|
||||
</Tab>
|
||||
<Tab label="Menu" value="menu"
|
||||
className={(this.state.tabSelected === 'menu') ? "buttonTabs buttonTabsActive" : 'buttonTabs'}>
|
||||
</Tab>
|
||||
<Tab label="Featured Categories" value="featured_categories"
|
||||
className={(this.state.tabSelected === 'featured_categories') ? "buttonTabs buttonTabsActive" : 'buttonTabs'}>
|
||||
</Tab>
|
||||
<Tab label="Featured Stores" value="featured_stores"
|
||||
className={(this.state.tabSelected === 'featured_stores') ? "buttonTabs buttonTabsActive" : 'buttonTabs'}>
|
||||
</Tab>
|
||||
|
||||
</Tabs>
|
||||
|
||||
{this.getContent()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
27
src/common/pages/LoadingDialog/index.js
Normal file
27
src/common/pages/LoadingDialog/index.js
Normal file
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
import {observer, inject} from 'mobx-react';
|
||||
import bind from 'bind-decorator';
|
||||
import {
|
||||
CircularProgress,
|
||||
Dialog
|
||||
} from 'material-ui';
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class LoadingComponent extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.globalUI = props.appstate.globalUI;
|
||||
}
|
||||
|
||||
render(){
|
||||
return (
|
||||
<div>
|
||||
<CircularProgress size={80} thickness={5} color="" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
108
src/common/pages/Login/Form.js
Normal file
108
src/common/pages/Login/Form.js
Normal file
@@ -0,0 +1,108 @@
|
||||
import React from "react";
|
||||
import {Button, Form, Input, Select} from "antd";
|
||||
const {Option, OptGroup} = Select;
|
||||
const FormItem = Form.Item;
|
||||
|
||||
class ComponentName extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
pass_min_length: 4
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
}
|
||||
|
||||
submit(e) {
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
this
|
||||
.props
|
||||
.form
|
||||
.validateFields((err, value) => {
|
||||
if (err) {
|
||||
return console.error(err);
|
||||
}
|
||||
|
||||
if (this.props.onSubmit && this.props.onSubmit instanceof Function) {
|
||||
this
|
||||
.props
|
||||
.onSubmit(this.props.form, Object.assign({}, value));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onCancel() {
|
||||
// todo, find better way to check if onCancel is a function
|
||||
if (this.props.onCancel && this.props.onCancel instanceof Function) {
|
||||
this
|
||||
.props
|
||||
.onCancel(this.props.form);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const {getFieldDecorator} = this.props.form;
|
||||
|
||||
const emailRule = getFieldDecorator('username', {
|
||||
rules: [
|
||||
{
|
||||
type: 'email',
|
||||
message: 'Email format not valid'
|
||||
}, {
|
||||
required: true,
|
||||
message: 'Please input your email'
|
||||
}
|
||||
],
|
||||
initialValue: this.props.username
|
||||
});
|
||||
|
||||
const passwordRule = getFieldDecorator('password', {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Please input your password'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
return (
|
||||
<Form>
|
||||
<FormItem>
|
||||
{emailRule(
|
||||
<Input className="box-input"
|
||||
placeholder="Email"/>
|
||||
)}
|
||||
</FormItem>
|
||||
|
||||
<FormItem>
|
||||
{passwordRule(
|
||||
<Input className="box-input'"
|
||||
type="password"
|
||||
placeholder="Password"/>
|
||||
)}
|
||||
</FormItem>
|
||||
|
||||
<Button
|
||||
style={{
|
||||
width: "100%",
|
||||
marginBottom: 10
|
||||
}}
|
||||
type="primary"
|
||||
size="large"
|
||||
onClick={() => this.submit()}>
|
||||
Sign in
|
||||
</Button>
|
||||
<p>{this.props.footer}</p>
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default Form.create()(ComponentName);
|
||||
273
src/common/pages/Login/index.js
Normal file
273
src/common/pages/Login/index.js
Normal file
@@ -0,0 +1,273 @@
|
||||
import React from 'react';
|
||||
import {Card, CardActions, CardText, CardTitle, Divider, Paper,RaisedButton, TextField,Dialog,FlatButton,} from 'material-ui';
|
||||
import {inject, observer} from 'mobx-react';
|
||||
import * as firebase from "firebase";
|
||||
import './style.scss'
|
||||
import {LINKS} from "../../routes";
|
||||
import {getMobileOperatingSystem} from '../../stores/firebase';
|
||||
import {Helmet} from "react-helmet";
|
||||
|
||||
|
||||
@inject('appstate')
|
||||
@observer
|
||||
export default class LoginComponent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.state = {
|
||||
email: "",
|
||||
password: "",
|
||||
warningLogin : false,
|
||||
warningLoginMessage : '',
|
||||
notif:false,
|
||||
};
|
||||
this.defaultState = Object.assign({}, this.state);
|
||||
this.authStore = props.appstate.auth;
|
||||
this.http = props.appstate.http;
|
||||
this.settingStore = props.appstate.setting;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.settingStore.getAll();
|
||||
const firebase = require('firebase');
|
||||
firebase.messaging().requestPermission()
|
||||
.then(function () {
|
||||
console.log('Notification permission granted.');
|
||||
return firebase.messaging().getToken();
|
||||
})
|
||||
.then(currentToken => {
|
||||
if (currentToken) {
|
||||
console.log(currentToken, "user tokens");
|
||||
localStorage.setItem('tokens', currentToken);
|
||||
} else {
|
||||
// Show permission request.
|
||||
console.log('No Instance ID token available. Request permission to generate one.');
|
||||
// Show permission UI.
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
handleTextFieldChange = (event, name) => {
|
||||
this.setState({
|
||||
[name]: event.target.value
|
||||
});
|
||||
};
|
||||
|
||||
login=(e)=>{
|
||||
firebase.messaging().requestPermission()
|
||||
.then(() => {
|
||||
// alert('bisa')
|
||||
|
||||
// e.preventDefault();
|
||||
var tokenNotif = localStorage.getItem('tokens');
|
||||
this.authStore.login({
|
||||
username: this.state.email,
|
||||
password: this.state.password,
|
||||
firebase_token: tokenNotif
|
||||
})
|
||||
.then(() => {
|
||||
localStorage.setItem('isLoggedIn', true);
|
||||
this.props.history.push(LINKS.DASHBOARD);
|
||||
console.log(this.state.email + " is logging in..")
|
||||
}).catch(err => {
|
||||
console.log(err);
|
||||
this.openWarningMessage(err.message);
|
||||
});
|
||||
|
||||
})
|
||||
.catch(error => {
|
||||
this.setState({
|
||||
notif:true
|
||||
})
|
||||
// alert('gk bisa')
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
openWarningMessage = (message)=>{
|
||||
this.setState({
|
||||
warningLoginMessage : message,
|
||||
warningLogin : true
|
||||
})
|
||||
}
|
||||
|
||||
closeWarning = ()=>{
|
||||
this.setState({
|
||||
warningLogin : false
|
||||
})
|
||||
}
|
||||
|
||||
handleClose = ()=>{
|
||||
this.setState({
|
||||
notif : false
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const actions = [
|
||||
<RaisedButton
|
||||
label={"Ok"}
|
||||
primary={true}
|
||||
onClick={()=>this.closeWarning()}
|
||||
/>,
|
||||
];
|
||||
|
||||
const actionsNotif = [
|
||||
<RaisedButton
|
||||
label="Done"
|
||||
primary={true}
|
||||
onClick={this.handleClose}
|
||||
/>,
|
||||
];
|
||||
|
||||
// const applicationIcon = (this.settingStore.isIconEmpty) ? "/assets/images/logo_ikan.png" : this.http.appendImagePath(this.settingStore.setting.icon);
|
||||
const applicationIcon = "/assets/images/logo_ikan.png";
|
||||
return (
|
||||
<div className="login login-wrapper">
|
||||
<Helmet>
|
||||
<meta charSet="utf-8"/>
|
||||
<title>{/*(this.settingStore.setting.name) ? this.settingStore.setting.name : ""*/'Marketplace'}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<link rel="icon" type="image/png" href={applicationIcon} sizes="96x96"/>
|
||||
</Helmet>
|
||||
<div style={{width: "100%"}}>
|
||||
{/*
|
||||
(this.settingStore.isIconEmpty) ?
|
||||
<div style={{textAlign: "center"}}>
|
||||
<Paper style={{
|
||||
backgroundSize: "contain",
|
||||
backgroundClip: "padding-box",
|
||||
padding: 10,
|
||||
height: 75, width: 75,
|
||||
background: '#fff',
|
||||
marginRight: "auto",
|
||||
marginLeft: "auto"
|
||||
}} zDepth={1} circle={true}>
|
||||
<img className="logo" src="/assets/images/logo_ikan.png"/>
|
||||
</Paper>
|
||||
<h2 style={{
|
||||
color: '#000',
|
||||
marginRight: "auto",
|
||||
marginLeft: "auto",
|
||||
maxWidth: 500,
|
||||
marginTop: 15,
|
||||
marginBottom: 0
|
||||
}}>5 Roti dan 2 Ikan</h2>
|
||||
</div>
|
||||
:
|
||||
<div style={{textAlign: "center"}}>
|
||||
<Paper style={{
|
||||
backgroundSize: "contain",
|
||||
backgroundClip: "padding-box",
|
||||
padding: 10,
|
||||
height: 75, width: 75,
|
||||
background: '#fff',
|
||||
marginRight: "auto",
|
||||
marginLeft: "auto"
|
||||
}} zDepth={1} circle={true}>
|
||||
<img className="logo"
|
||||
src={this.http.appendImagePath(this.settingStore.setting.icon)}/>
|
||||
</Paper>
|
||||
<h2 style={{
|
||||
color: '#275164',
|
||||
marginRight: "auto",
|
||||
marginLeft: "auto",
|
||||
maxWidth: 500,
|
||||
marginTop: 15,
|
||||
marginBottom: 0
|
||||
}}>{this.settingStore.setting.name}</h2>
|
||||
</div>
|
||||
*/
|
||||
}
|
||||
<div style={{textAlign: "center"}}>
|
||||
<Paper style={{
|
||||
backgroundSize: "contain",
|
||||
backgroundClip: "padding-box",
|
||||
padding: 10,
|
||||
height: 75, width: 75,
|
||||
background: '#fff',
|
||||
marginRight: "auto",
|
||||
marginLeft: "auto"
|
||||
}} zDepth={1} circle={true}>
|
||||
<img className="logo" src={applicationIcon}/>
|
||||
</Paper>
|
||||
<h2 style={{
|
||||
color: '#000',
|
||||
marginRight: "auto",
|
||||
marginLeft: "auto",
|
||||
maxWidth: 500,
|
||||
marginTop: 15,
|
||||
marginBottom: 0
|
||||
}}>Marketplace</h2>
|
||||
</div>
|
||||
</div>
|
||||
<Card style={{width: 350, marginTop: '18px'}} className="cardLite align-center">
|
||||
<CardTitle title={<p style={{fontSize: 14}}>Login to Store Admin Console</p>}>
|
||||
<Divider style={{backgroundColor: 'rgba(171, 111, 48, 1)', width: '150px'}} className="margin-auto"/>
|
||||
</CardTitle>
|
||||
|
||||
<form>
|
||||
<CardText>
|
||||
<TextField
|
||||
hintText="Email"
|
||||
fullWidth={true}
|
||||
name="email"
|
||||
type="email"
|
||||
value={this.state.email}
|
||||
onChange={(event) => this.handleTextFieldChange(event, 'email')}
|
||||
/>
|
||||
<TextField
|
||||
hintText="Password"
|
||||
name="password"
|
||||
fullWidth={true}
|
||||
type="password"
|
||||
value={this.state.password}
|
||||
onChange={(event) => this.handleTextFieldChange(event, 'password')}
|
||||
onKeyPress={(ev) => {
|
||||
if (ev.key === 'Enter') {
|
||||
// Do code here
|
||||
this.login()
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</CardText>
|
||||
<CardActions>
|
||||
<RaisedButton primary={true} label="Login To Your Account" onClick={this.login}/>
|
||||
</CardActions>
|
||||
<a style={{fontSize: 12, fontWeight: 500, display: 'block', margin: '18px 0px 30px'}}
|
||||
onClick={() => this.props.history.push(LINKS.FORGOT_PASSWORD)}>Forgot Password</a>
|
||||
</form>
|
||||
</Card>
|
||||
<Dialog
|
||||
title="Error"
|
||||
actions={actions}
|
||||
modal={true}
|
||||
open={this.state.warningLogin}
|
||||
onRequestClose={() => this.closeWarning()}
|
||||
>
|
||||
{this.state.warningLoginMessage}
|
||||
</Dialog>
|
||||
<Dialog
|
||||
title="Warning"
|
||||
actions={actionsNotif}
|
||||
open={this.state.notif}
|
||||
autoScrollBodyContent={true}
|
||||
modal={false}
|
||||
>
|
||||
<p>1. You must allow notification</p>
|
||||
<div style={{textAlign:'center'}}>
|
||||
<img src="/assets/images/notification.jpg" style={{height : '400px'}}/>
|
||||
</div>
|
||||
<p style={{marginTop:'1em'}}>2. Reload Page</p>
|
||||
<div style={{textAlign:'center'}}>
|
||||
<img style={{height: "400px"}} src="/assets/images/reload.jpg"/>
|
||||
</div>
|
||||
{/*<p>1. You must allow notification</p>
|
||||
<img style={{width: "100%", height: "100%"}} src="/assets/images/notification.jpg"/>*/}
|
||||
</Dialog>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
83
src/common/pages/Login/style.scss
Normal file
83
src/common/pages/Login/style.scss
Normal file
@@ -0,0 +1,83 @@
|
||||
.login {
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
//background-size: cover;
|
||||
//position: fixed;
|
||||
//height: 100%;
|
||||
//width: 100%;
|
||||
//top:0;
|
||||
//overflow: hidden;
|
||||
.logo {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.background {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background: rgba(128, 0, 128, 0.82); /* fallback for old browsers */
|
||||
background: -webkit-linear-gradient(to top, rgba(0, 204, 187, 0.86), rgba(43, 69, 230, 0.91), rgba(128, 0, 128, 0.92)); /* Chrome 10-25, Safari 5.1-6 */
|
||||
background: linear-gradient(to top, rgba(0, 204, 187, 0.86), rgba(43, 69, 230, 0.91), rgba(128, 0, 128, 0.92));
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
.ant-form-explain {
|
||||
text-align: left;
|
||||
}
|
||||
.login-box {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 460px;
|
||||
height: 320px;
|
||||
padding: 36px;
|
||||
background-color: #1e2e4a;
|
||||
box-shadow: 0 0 100px rgba(0, 0, 0, .08);
|
||||
.header {
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
margin-bottom: 24px;
|
||||
img {
|
||||
width: 40px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
span {
|
||||
vertical-align: text-bottom;
|
||||
font-size: 16px;
|
||||
text-transform: uppercase;
|
||||
display: inline-block;
|
||||
}
|
||||
p {
|
||||
font-size: 16px;
|
||||
text-transform: uppercase;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
//.login::before {
|
||||
// content: "";
|
||||
// position: absolute;
|
||||
// z-index: -1;
|
||||
// background: -webkit-gradient(linear, left top, right bottom, from(#D7BBEA), to(#65A8F1));
|
||||
// background: linear-gradient(to bottom right, #D7BBEA, #65A8F1);
|
||||
// top: 0;
|
||||
// left: 0;
|
||||
// bottom: 0;
|
||||
// right: 0;
|
||||
//}
|
||||
|
||||
//.login-wrapper {
|
||||
// margin: 0 auto;
|
||||
// position: relative;
|
||||
// min-height: 100%;
|
||||
// box-shadow: none;
|
||||
// border-radius: 0;
|
||||
// background-image: url('/assets/images/bg-pattern2.png');
|
||||
// background-size: contain;
|
||||
// background-repeat: repeat;
|
||||
// background-position: 0 0;
|
||||
//}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user