Initial commit

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

7
src/client/global.scss Normal file
View File

@@ -0,0 +1,7 @@
.text-right {
text-align: right
}
.text-center {
text-align: center
}

79
src/client/index.js Normal file
View 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')
);

View 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>);
}
}

View 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
View 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
View 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"
}
};

View 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);

View 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>
)
}
}

View 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;
}
}
}
}

View 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>
);
}
}

View 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>
)
}
}

View 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;
}
}

View 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>
)
}
}

View 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>
);
}
}

View 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>
)
}
}

View 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>
)
}
}

View 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>
)
}
}

View 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>
)
}
}

View 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>
)
}
}

View 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>
)
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -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> )
}
}

View 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>
)
}
}

View 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>
)
}
}

View File

@@ -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>
)
}
}

View File

@@ -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>
)
}
}

View File

@@ -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>
)
}
}

View File

@@ -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>
)
}
}

View File

@@ -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>
)
}
}

View File

@@ -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>
)
}
}

View 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>
)
}
}

View 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>
)
}
}

View 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>
)
}
}

View 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>
)
}
}

View 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>
)
}
}

View 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;
}
}

View 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>
);
}
}

View 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>
);
}
}

View File

@@ -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>
);
}
}

View 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>
)
}
}

View 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>
)
}
}

View 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>
)
}
}

View 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>
)
}
}

View 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>
);
}
}

View 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>
)
}
}

View 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;
}
}

View 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>
)
}
}

View 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>
)
}
}

View 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>
)
}
}

View 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>
)
}
}

View 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>
);
}
}
}

View 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>
)
}
}

View File

@@ -0,0 +1,9 @@
.empty-state {
height: 100%;
width: 100%;
text-align: center;
.message-container {
position: relative;
}
}

View 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>
)
}
}

View 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>
);
}
}

View 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>
)
}
}

View 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>
)
}
}

View 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>
);
}
}

View 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>
)
}
}

View 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>
)
}
}

View 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>
);
}
}

View 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>
)
}
}

View 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>
)
}
}

View 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);

View 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>
)
}
}

View 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;
}
}
}
}

View 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>
)
}
}

View 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>
)
}
}

View 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>
);
}
}

View 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;
}

View 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>
)
}
}

View 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%;
}
}

View 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);

View 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>
)
}
}

View 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;
}
}
}
}

View 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);

View 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>
)
}
}

View 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;
}
}
}
}

View 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>
)
}
}

View 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>
)
}
}

View 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>
)
}
}

View 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}/>
)
}
}

File diff suppressed because it is too large Load Diff

View 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>
)
}
}

View 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>
)
}
}

View 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}/>
)
}
}

View 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>
)
}
}

View 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>
)
}
}

View 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>
)
}
}

View 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>
)
}
}

View 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>
)
}
}

View 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;
}

View 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>
)
}
}

View 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>
);
}
}

View 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);

View 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>
)
}
}

View 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