Browse Source

Merge pull request 'Dev-Farhan' (#62) from Dev-Farhan into staging

Reviewed-on: ibnu/generic-ospro-frontend#62
pull/1/head
farhantock 10 months ago
parent
commit
8474bbc830
  1. 57
      src/const/ApiConst.js
  2. 7
      src/const/en.json
  3. 7
      src/const/id.json
  4. 2
      src/containers/DefaultLayout/DefaultLayout.js
  5. 11
      src/routes.js
  6. 158
      src/views/Master/MasterRoles/DialogMenuRoles.js
  7. 9
      src/views/Master/MasterRoles/index.js
  8. 0
      src/views/SimproV2/DemoRequest/DialogForm.js
  9. 4
      src/views/SimproV2/DemoRequest/index.js
  10. 190
      src/views/SimproV2/ReferralCode/DialogForm.js
  11. 372
      src/views/SimproV2/ReferralCode/index.js
  12. 201
      src/views/SimproV2/SalesContact/DialogForm.js
  13. 374
      src/views/SimproV2/SalesContact/index.js

57
src/const/ApiConst.js

@ -118,7 +118,6 @@ export const TOKEN_ADW =
// export let BASE_OSPRO = "https://ospro-api.ospro.id";
// export let BASE_OSPRO = "https://project-api.ospro.id";
export let BASE_OSPRO = "http://localhost:8444/generic-ospro-backend";
// export let BASE_OSPRO = "http://103.73.125.81:8444"; // ip public adw
export let BASE_SIMPRO_LUMEN = `${BASE_OSPRO}/api`;
export let BASE_SIMPRO_LUMEN_IMAGE = `${BASE_OSPRO}/assets/image`;
export let BASE_SIMPRO_LUMEN_FILE = `${BASE_OSPRO}/assets/file/project`;
@ -128,36 +127,6 @@ export let BASE_SIMPRO_LUMEN_FILE_COMPANY = (file, company_name)=>{
export let BASE_SIMPRO_LUMEN_IMAGE_COMPANY = (file, company_name) => {
return `${BASE_OSPRO}/assets/${company_name}/image/${file}`;
}
// switch (APP_MODE) {
// case 'KIT':
// BASE_OSPRO = "https://kit-api.oslogdev.com"
// //for KIT server
// // BASE_SIMPRO_LUMEN = `${BASE_OSPRO}/api`;
// // BASE_SIMPRO_LUMEN_IMAGE = `${BASE_SIMPRO_LUMEN}/assets/image`;
// // BASE_SIMPRO_LUMEN_FILE = `${BASE_SIMPRO_LUMEN}/assets/file/project`;
// break;
// case 'ADW':
// // BASE_OSPRO = "https://adw-api.ospro.id"
// BASE_OSPRO = "http://103.73.125.81:8444";
// BASE_SIMPRO_LUMEN = `${BASE_OSPRO}/api`;
// BASE_SIMPRO_LUMEN_IMAGE = `${BASE_OSPRO}/assets/image`;
// BASE_SIMPRO_LUMEN_FILE = `${BASE_OSPRO}/assets/file/project`;
// break;
// case 'IU':
// BASE_OSPRO = "https://api-iu.ospro.id"
// BASE_SIMPRO_LUMEN = `${BASE_OSPRO}/api`;
// BASE_SIMPRO_LUMEN_IMAGE = `${BASE_OSPRO}/assets/image`;
// BASE_SIMPRO_LUMEN_FILE = `${BASE_OSPRO}/assets/file/project`;
// break;
// default:
// BASE_OSPRO = "https://ospro-api.ospro.id"
// }
export const USERROLE_ADD = `${BASE_SIMPRO}/user-role/add`;
export const USERROLE_SEARCH = `${BASE_SIMPRO}/user-role/search`;
@ -849,8 +818,6 @@ export const MENU_COMPANY_DELETE = (id) => {
return `${BASE_SIMPRO_LUMEN}/menu-company/delete/${id}`;
};
export const DEMO_MANAGEMENT_ADD = `${BASE_SIMPRO_LUMEN}/demo-management/add`;
export const DEMO_MANAGEMENT_SEARCH = `${BASE_SIMPRO_LUMEN}/demo-management/search`;
export const DEMO_MANAGEMENT_EDIT = (id) => {
@ -863,3 +830,27 @@ export const DEMO_MANAGEMENT_DELETE = (id) => {
return `${BASE_SIMPRO_LUMEN}/demo-management/delete/${id}`;
};
export const DEMO_MANAGEMENT_LIST = `${BASE_SIMPRO_LUMEN}/demo-management/list`;
export const REFERRAL_CODE_ADD = `${BASE_SIMPRO_LUMEN}/refferal-code/add`;
export const REFERRAL_CODE_SEARCH = `${BASE_SIMPRO_LUMEN}/refferal-code/search`;
export const REFERRAL_CODE_EDIT = (id) => {
return `${BASE_SIMPRO_LUMEN}/refferal-code/update/${id}`;
};
export const REFERRAL_CODE_GET_ID = (id) => {
return `${BASE_SIMPRO_LUMEN}/refferal-code/edit/${id}`;
};
export const REFERRAL_CODE_DELETE = (id) => {
return `${BASE_SIMPRO_LUMEN}/refferal-code/delete/${id}`;
};
export const SALES_CONTACT_ADD = `${BASE_SIMPRO_LUMEN}/sales-contact/add`;
export const SALES_CONTACT_SEARCH = `${BASE_SIMPRO_LUMEN}/sales-contact/search`;
export const SALES_CONTACT_EDIT = (id) => {
return `${BASE_SIMPRO_LUMEN}/sales-contact/update/${id}`;
};
export const SALES_CONTACT_GET_ID = (id) => {
return `${BASE_SIMPRO_LUMEN}/sales-contact/edit/${id}`;
};
export const SALES_CONTACT_DELETE = (id) => {
return `${BASE_SIMPRO_LUMEN}/sales-contact/delete/${id}`;
};

7
src/const/en.json

@ -1,6 +1,8 @@
{
"3days": "3 Days Ago",
"7days": "7 Days Ago",
"amount": "Amount",
"allocation": "Allocation",
"action": "Action",
"add": "Add",
"address": "Address",
@ -16,6 +18,8 @@
"cancel": "Cancel",
"close": "Close",
"color": "Color",
"code": "Code",
"discount": "Discount",
"date": "Date",
"dateSend": "Send Date",
"dateAbsent": "Absent Date",
@ -37,6 +41,7 @@
"demoAdd": "Add Demo",
"employeeType": "Employee Type",
"edit": "Edit",
"exp": "Expire",
"export": "Export",
"exportExcel": "Export Excel",
"exportPdf": "Export Pdf",
@ -54,6 +59,8 @@
"inputDescription": "Input Description",
"inputParentMenu": "Select Parent Menu",
"inputAliasMenu": "Input Menu Alias",
"inputAmount": "Input Amount",
"inputCode": "Input Code",
"inputOrder": "Input Order",
"inputUrl": "Input URL",
"inputMsg": "Input Message",

7
src/const/id.json

@ -1,6 +1,8 @@
{
"3days": "3 Hari Yang lalu",
"7days": "7 Hari Yang lalu",
"amount": "Jumlah",
"allocation": "Kuota",
"action": "Aksi",
"add": "Tambah",
"address": "Alamat",
@ -16,6 +18,8 @@
"cancel": "Batal",
"close": "Tutup",
"color": "Warna",
"code": "Kode",
"discount": "Diskon",
"date": "Tanggal",
"dateSend": "Tanggal Kirim",
"dateAbsent": "Tanggal Absen",
@ -36,6 +40,7 @@
"divisionAdd": "Tambah Divisi",
"demoAdd": "Tambah Demo",
"edit": "Ubah",
"exp": "Batas Waktu",
"export": "Ekspor",
"exportExcel": "Ekspor Excel",
"exportPdf": "Ekspor Pdf",
@ -69,6 +74,8 @@
"inputNik": "Masukan NIK (KTP)",
"inputMessage": "Masukan Pesan",
"inputRole": "Masukan Peran",
"inputAmount": "Masukan Jumlah",
"inputCode": "Masukan Kode",
"image": "Gambar",
"imageCheck": "Lihat Selfie Presensi",
"locIn": "Lokasi Masuk",

2
src/containers/DefaultLayout/DefaultLayout.js

@ -111,8 +111,6 @@ class DefaultLayout extends Component {
default:
faviconElement.type = 'image/png';
}
console.log('faviconElement.type', faviconElement.type);
console.log('faviconContent', faviconContent);
faviconElement.href = faviconContent || `${process.env.PUBLIC_URL}/OSPRO.ico`;

11
src/routes.js

@ -56,7 +56,9 @@ const DashboardProjectCarousell = React.lazy(() => import('./views/Dashboard/Das
const MapMonitoring = React.lazy(() => import('./views/MapMonitoring'));
const Settings = React.lazy(() => import('./views/SimproV2/Settings/Desktop'));
const CompanyManagement = React.lazy(() => import('./views/Master/MasterCompany'))
const DemoManagement = React.lazy(() => import('./views/SimproV2/Demo'))
const DemoRequest = React.lazy(() => import('./views/SimproV2/DemoRequest'))
const ReferralCode = React.lazy(() => import('./views/SimproV2/ReferralCode'))
const SalesContact = React.lazy(() => import('./views/SimproV2/SalesContact'))
const routes = [
{ path: '/', exact: true, name: 'Home' },
{ path: '/dashboard', name: 'DashboardBOD', component: DashboardBOD },
@ -119,8 +121,11 @@ const routes = [
{ path: '/map-monitoring', exact: true, name: 'Map Monitoring', component: MapMonitoring },
// { path: '/dashboard-project/:ID/:GANTTID', exact: true, name: 'Dashboard Project', component: DashboardProject },
{ path: '/settings', exact: true, name: 'Settings', component: Settings },
{ path: '/company-management', exact: true, name: 'Company Management', component: CompanyManagement },
{ path: '/demo-management', exact: true, name: 'Demo Management', component: DemoManagement },
{ path: '/register-management', exact: true, name: 'Register Management', component: CompanyManagement },
{ path: '/demo-request', exact: true, name: 'Request Demo', component: DemoRequest },
{ path: '/referral-code-management', exact: true, name: 'Referral Code Management', component: ReferralCode },
{ path: '/sales-contact', exact: true, name: 'Sales Contact', component: SalesContact },
];
export default routes;

158
src/views/Master/MasterRoles/DialogMenuRoles.js

@ -3,7 +3,7 @@ import { Modal, ModalHeader, ModalBody, ModalFooter, Row, Col, Table } from 'rea
import { Button, Form, FormGroup, Label, Input } from 'reactstrap';
import 'antd/dist/antd.css';
import axios from 'axios';
import { MENU_SEARCH } from '../../../const/ApiConst.js';
import { MENU_COMPANY_SEARCH } from '../../../const/ApiConst.js';
const token = window.localStorage.getItem('token');
@ -36,6 +36,7 @@ export default class DialogMenuRoles extends Component {
stateUpdateAll: false,
stateDeleteAll: false,
allChecked: true,
company_id: props.company_id || null,
}
}
async componentDidMount() {
@ -64,10 +65,11 @@ export default class DialogMenuRoles extends Component {
const payload = {
"paging": { "start": 0, "length": -1 },
"columns": [
{ "name": "name", "logic_operator": "ilike", "value": "", "operator": "AND" }
{ "name": "company_id", "logic_operator": "=", "value": this.state.company_id, "operator": "AND" }
],
"joins": [
{ "name": "t_roles_menu", "column_join": "id", "column_results": ["create", "update", "delete", "read"] }
{ "name": "t_roles_menu", "column_join": "menu_id", "column_results": ["create", "update", "delete", "read"] },
{ "name": "m_menu", "column_join": "menu_id", "column_results": ["name"] }
],
"orders": { "columns": ["id"], "ascending": false }
}
@ -75,11 +77,9 @@ export default class DialogMenuRoles extends Component {
const result = await axios
.post(MENU_SEARCH, payload, config)
.post(MENU_COMPANY_SEARCH, payload, config)
.then(res => res)
.catch((error) => error.response);
// console.log('78', result);
if (result && result.data && result.data.code == 200) {
this.setState({ menu: result.data.data }, () => {
this.setStateMenu(false);
@ -321,8 +321,7 @@ export default class DialogMenuRoles extends Component {
})
console.log('arrayData', arrayData);
// this.props.closeDialog('save', arrayData);
this.props.closeDialog('save', arrayData);
this.setState({ id: 0 });
}
@ -337,31 +336,104 @@ export default class DialogMenuRoles extends Component {
this.setState({ stateMenu: copyStateMenu })
}
handleChangeCheckboxRead = (checked, index) => {
handleChangeCheckboxRead = (checked, index, menuItem = null, menuIdxList = []) => {
let copyStateRead = [...this.state.stateRead];
copyStateRead[index] = checked;
let menu = this.state.menu;
let checkMenuParent = menu.map((state, index) => {
if (state.parent_menu_id === menuItem.menu_id) {
return state.menu_id
} else {
return null
}
}).filter(index => index !== null);
let stateReadIdx = [];
menuIdxList.forEach((menu, index) => {
checkMenuParent.forEach((check, idx) => {
if (check === menu) {
stateReadIdx.push(index);
}
});
});
stateReadIdx.map((stateRead) => {
copyStateRead[stateRead] = checked
})
this.setState({ stateRead: copyStateRead })
}
handleChangeCheckboxCreate = (checked, index) => {
handleChangeCheckboxCreate = (checked, index, menuItem = null, menuIdxList = []) => {
let copyStateCreate = [...this.state.stateCreate];
copyStateCreate[index] = checked;
let menu = this.state.menu;
let checkMenuParent = menu.map((state, index) => {
if (state.parent_menu_id === menuItem.menu_id) {
return state.menu_id
} else {
return null
}
}).filter(index => index !== null);
let stateCreateIdx = [];
menuIdxList.forEach((menu, index) => {
checkMenuParent.forEach((check, idx) => {
if (check === menu) {
stateCreateIdx.push(index);
}
});
});
stateCreateIdx.map((stateCreate) => {
copyStateCreate[stateCreate] = checked
})
this.setState({ stateCreate: copyStateCreate })
}
handleChangeCheckboxEdit = (checked, index) => {
handleChangeCheckboxEdit = (checked, index, menuItem = null, menuIdxList = []) => {
let copyStateEdit = [...this.state.stateUpdate];
copyStateEdit[index] = checked;
let menu = this.state.menu;
let checkMenuParent = menu.map((state, index) => {
if (state.parent_menu_id === menuItem.menu_id) {
return state.menu_id
} else {
return null
}
}).filter(index => index !== null);
let stateEditIdx = [];
menuIdxList.forEach((menu, index) => {
checkMenuParent.forEach((check, idx) => {
if (check === menu) {
stateEditIdx.push(index);
}
});
});
stateEditIdx.map((stateEdit) => {
copyStateEdit[stateEdit] = checked
})
this.setState({ stateUpdate: copyStateEdit })
}
handleChangeCheckboxDelete = (checked, index) => {
handleChangeCheckboxDelete = (checked, index, menuItem = null, menuIdxList = []) => {
let copyStateDelete = [...this.state.stateDelete];
copyStateDelete[index] = checked;
let menu = this.state.menu;
let checkMenuParent = menu.map((state, index) => {
if (state.parent_menu_id === menuItem.menu_id) {
return state.menu_id
} else {
return null
}
}).filter(index => index !== null);
let stateDeleteIdx = [];
menuIdxList.forEach((menu, index) => {
checkMenuParent.forEach((check, idx) => {
if (check === menu) {
stateDeleteIdx.push(index);
}
});
});
stateDeleteIdx.map((stateDelete) => {
copyStateDelete[stateDelete] = checked
})
this.setState({ stateDelete: copyStateDelete })
}
@ -397,61 +469,43 @@ export default class DialogMenuRoles extends Component {
this.setState({ stateDelete: copyStateDelete })
}
// renderForm = () => {
// const { menu, stateRead, stateCreate, stateUpdate, stateDelete } = this.state
// console.log('menu', menu);
// return (
// menu.map((val, index) => {
// return (
// <tr key={index}>
// <td>{val.name}</td>
// <td><input type="checkbox" onClick={(e) => this.handleChangeCheckboxRead(e.target.checked, index)} defaultChecked={stateRead[index]} /></td>
// <td><input type="checkbox" onClick={(e) => this.handleChangeCheckboxCreate(e.target.checked, index)} defaultChecked={stateCreate[index]} /></td>
// <td><input type="checkbox" onClick={(e) => this.handleChangeCheckboxEdit(e.target.checked, index)} defaultChecked={stateUpdate[index]} /></td>
// <td><input type="checkbox" onClick={(e) => this.handleChangeCheckboxDelete(e.target.checked, index)} defaultChecked={stateDelete[index]} /></td>
// </tr>
// )
// })
// )
// }
renderForm = () => {
const { menu, stateRead, stateCreate, stateUpdate, stateDelete } = this.state;
let menuIdxList = []
let menuIdx = 0
const getChildren = (parentId) => {
return menu.filter(item => item.parent_id === parentId);
return menu.filter(item => item.parent_menu_id === parentId);
};
// Function to render menu items
const renderMenu = (parentId, depth = 0) => {
const children = getChildren(parentId);
return children.map((menuItem, index) => {
const paddingLeft = depth * 20;
const fontWeight = menuItem.parent_id === null ? 'bold' : 'normal';
const currentIndex = menuIdx;
menuIdxList[currentIndex] = menuItem.menu_id;
menuIdx++
const paddingLeft = depth * 30;
return (
<React.Fragment key={index}>
<React.Fragment key={menuIdx - 1}>
<tr >
<td style={{ paddingLeft: paddingLeft }}>{menuItem.name}</td>
<td><input type="checkbox" onClick={(e) => this.handleChangeCheckboxRead(e.target.checked, index)} defaultChecked={stateRead[index]} /></td>
<td><input type="checkbox" onClick={(e) => this.handleChangeCheckboxCreate(e.target.checked, index)} defaultChecked={stateCreate[index]} /></td>
<td><input type="checkbox" onClick={(e) => this.handleChangeCheckboxEdit(e.target.checked, index)} defaultChecked={stateUpdate[index]} /></td>
<td><input type="checkbox" onClick={(e) => this.handleChangeCheckboxDelete(e.target.checked, index)} defaultChecked={stateDelete[index]} /></td>
<td style={{ paddingLeft: paddingLeft }}>{menuItem.join_second_name}</td>
<td><input type="checkbox" onClick={(e) => this.handleChangeCheckboxRead(e.target.checked, currentIndex, menuItem, menuIdxList)} defaultChecked={stateRead[currentIndex]} /></td>
<td><input type="checkbox" onClick={(e) => this.handleChangeCheckboxCreate(e.target.checked, currentIndex, menuItem, menuIdxList)} defaultChecked={stateCreate[currentIndex]} /></td>
<td><input type="checkbox" onClick={(e) => this.handleChangeCheckboxEdit(e.target.checked, currentIndex, menuItem, menuIdxList)} defaultChecked={stateUpdate[currentIndex]} /></td>
<td><input type="checkbox" onClick={(e) => this.handleChangeCheckboxDelete(e.target.checked, currentIndex, menuItem, menuIdxList)} defaultChecked={stateDelete[currentIndex]} /></td>
</tr>
{renderMenu(menuItem.id, depth + 1)} {/* Recursively render children */}
{renderMenu(menuItem.menu_id, depth + 1)}
</React.Fragment>
);
});
};
// Render top-level menu items (parents)
menuIdxList = []
menuIdx = 0
return (
<React.Fragment>
{this.renderAll()} {/* Render the "All" row */}
{renderMenu(null)} {/* Render the menu items */}
{this.renderAll()}
{renderMenu(null)}
</React.Fragment>
);
};
@ -525,7 +579,7 @@ export default class DialogMenuRoles extends Component {
Create
</th>
<th>
Edite
Edit
</th>
<th>
Delete

9
src/views/Master/MasterRoles/index.js

@ -331,10 +331,15 @@ class index extends Component {
let promises = []
let result = []
dataArray.map((val, index) => {
if (val.checked === true) {
if (val.read === true) {
const formData = {
menu_id: val.menu_id,
role_id: val.roles_id
role_id: val.roles_id,
create: val.create,
read: val.read,
update: val.update,
delete: val.delete
}
promises.push(axios.post(ROLEMENU_ADD, formData, this.state.config)
.then(res => result.push(res)))

0
src/views/SimproV2/Demo/DialogForm.js → src/views/SimproV2/DemoRequest/DialogForm.js

4
src/views/SimproV2/Demo/index.js → src/views/SimproV2/DemoRequest/index.js

@ -202,7 +202,7 @@ const ProjectType = ({ params, ...props }) => {
if (type === "save") {
saveDemo(data);
} else if (type === "edit") {
editMaterialR(data);
editDemo(data);
}
setDataEdit([])
setOpenDialog(false)
@ -221,7 +221,7 @@ const ProjectType = ({ params, ...props }) => {
}
}
const editMaterialR = async (data) => {
const editDemo = async (data) => {
let urlEdit = DEMO_MANAGEMENT_EDIT(data.id)
const formData = data
const result = await axios.put(urlEdit, formData, HEADER)

190
src/views/SimproV2/ReferralCode/DialogForm.js

@ -0,0 +1,190 @@
import React, { useEffect, useState } from 'react'
import {
Modal, ModalHeader, ModalBody, ModalFooter,
Button, Form, FormGroup, Label, Input, Col, Row
} from 'reactstrap';
import { Select, DatePicker } from 'antd';
import 'antd/dist/antd.css';
import { useTranslation } from 'react-i18next';
import "rc-color-picker/assets/index.css";
import moment from 'moment';
import { formatNumber } from "../../../const/CustomFunc";
const { Option } = Select
const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit }) => {
const [id, setId] = useState(0)
const [code, setCode] = useState('')
const [amount, setAmount] = useState(0)
const [description, setDescription] = useState('')
const [exp, setExp] = useState('')
const [type, setType] = useState('')
const [allocation, setAllocation] = useState(0)
const { t } = useTranslation()
useEffect(() => {
console.log('dataEdit', dataEdit);
if (typeDialog === "Edit") {
setId(dataEdit.id)
setCode(dataEdit.code)
setAmount(dataEdit.amount)
setDescription(dataEdit.description)
setExp(dataEdit.exp)
setType(dataEdit.type)
} else {
handleClear()
}
}, [dataEdit, openDialog])
const validation = () => {
if (!code || code === "") {
alert("Code cannot be empty!");
return true;
}
}
const handleSave = () => {
let data = '';
const err = validation();
if (!err) {
if (typeDialog === "Save") {
data = {
code,
amount,
description,
exp,
type,
allocation
}
console.log('data', data);
closeDialog('save', data);
} else {
data = {
id,
code,
amount,
description,
exp,
type,
allocation
}
console.log('data', data);
closeDialog('edit', data);
}
handleClear()
}
}
const handleCancel = () => {
closeDialog('cancel', 'none')
handleClear()
}
const handleClear = () => {
setId(0)
setCode('')
setAmount('')
setDescription('')
setExp('')
}
const renderForm = () => {
return (
<Form>
<Row>
<Col md={12}>
<span style={{ color: "red" }}>*</span> Wajib diisi.
</Col>
</Row>
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize">{t('code')} {t('discount')}<span style={{ color: "red" }}>*</span></Label>
<Input
type="text"
value={code}
onChange={(e) => setCode(e.target.value)}
placeholder={t('inputCode')}
/>
</FormGroup>
</Col>
<Col md={6}>
<FormGroup>
<Label className="capitalize">{t('amount')}<span style={{ color: "red" }}>*</span></Label>
<Input
type="text"
value={amount}
onChange={(e) => setAmount(e.target.value)}
placeholder={t('inputAmount')}
/>
</FormGroup>
</Col>
</Row>
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize" style={{ fontWeight: "bold" }}>
{t('exp')}<span style={{ color: "red" }}>*</span>
</Label>
<DatePicker
format={"DD-MM-YYYY HH:mm"}
style={{ width: "100%" }}
value={exp ? moment(exp) : exp}
onChange={(date, dateString) => setExp(date)}
showTime={{ defaultValue: moment('00:00:00', 'HH:mm:ss') }}
/>
</FormGroup>
</Col>
<Col md={6}>
<FormGroup>
<Label className="capitalize">{t('allocation')}<span style={{ color: "red" }}>*</span></Label>
<Input
type="number"
value={allocation}
onChange={(e) => setAllocation(e.target.value)}
placeholder={t('input')}
/>
</FormGroup>
</Col>
<Col md={6}>
<FormGroup>
<Label className="capitalize">{t('type')}<span style={{ color: "red" }}>*</span></Label>
<Input
type="text"
value={type}
onChange={(e) => setType(e.target.value)}
placeholder={t('inputType')}
/>
</FormGroup>
</Col>
</Row>
<Row>
<Col md={12}>
<FormGroup>
<Label className="capitalize">{t('description')}</Label>
<Input row="4" type="textarea" value={description} onChange={(e) => setDescription(e.target.value)} placeholder={t('inputDescription')} />
</FormGroup>
</Col>
</Row>
</Form>
)
}
return (
<>
<Modal size="lg" isOpen={openDialog} toggle={toggleDialog}>
<ModalHeader className="capitalize" toggle={closeDialog}>{typeDialog == "Save" ? `Add` : "Edit"} {t('Demo')}</ModalHeader>
<ModalBody>
{renderForm()}
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={() => handleSave()}>{typeDialog}</Button>{' '}
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>{t('cancel')}</Button>
</ModalFooter>
</Modal>
</>
)
}
export default DialogForm;

372
src/views/SimproV2/ReferralCode/index.js

@ -0,0 +1,372 @@
import * as XLSX from 'xlsx';
import DialogForm from './DialogForm';
import React, { useState, useEffect } from 'react';
import SweetAlert from 'react-bootstrap-sweetalert';
import axios from "../../../const/interceptorApi"
import { Card, CardBody, CardHeader, Col, Row, Input, Table } from 'reactstrap';
import { REFERRAL_CODE_EDIT, REFERRAL_CODE_SEARCH, REFERRAL_CODE_ADD, REFERRAL_CODE_DELETE } from '../../../const/ApiConst';
import { NotificationContainer, NotificationManager } from 'react-notifications';
import { Spin, Button, Tooltip } from 'antd';
import { useTranslation } from 'react-i18next';
import moment from 'moment';
import toRupiah from '@develoka/angka-rupiah-js';
const ProjectType = ({ params, ...props }) => {
let role_id = 0, user_id = 0, isLogin = false, token = '', company_id = 0, all_project = null, role_name = '', hierarchy = [], user_name = '';
if (props && props.role_id && props.user_id) {
role_id = props.role_id;
user_id = props.user_id;
token = props.token;
isLogin = props.isLogin;
company_id = props.company_id;
all_project = props.all_project;
role_name = props.role_name;
isLogin = props.isLogin;
hierarchy = props.hierarchy;
user_name = props.user_name;
}
const HEADER = {
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`
}
}
const pageName = params.name;
const [alertDelete, setAlertDelete] = useState(false)
const [allDataMenu, setAllDataMenu] = useState([])
const [clickOpenModal, setClickOpenModal] = useState(false)
const [currentPage, setCurrentPage] = useState(1)
const [dataEdit, setDataEdit] = useState([])
const [dataExport, setDataExport] = useState([])
const [dataTable, setDatatable] = useState([])
const [idDelete, setIdDelete] = useState(0)
const [openDialog, setOpenDialog] = useState(false)
const [rowsPerPage, setRowsPerPage] = useState(10)
const [search, setSearch] = useState("")
const [totalPage, setTotalPage] = useState(0)
const [typeDialog, setTypeDialog] = useState('Save')
const [dataDemo, setDataDemo] = useState([])
const [listCompany, setListCompany] = useState([])
const [loading, setLoading] = useState(true);
const { t } = useTranslation()
const column = [
{ name: t('code') },
{ name: t('type') },
{ name: t('amount') },
{ name: t('exp') },
{ name: t('allocation') },
{ name: t('description') },
].filter(column => column && column.name);
useEffect(() => {
getReferralCode();
}, [currentPage, rowsPerPage, search])
useEffect(() => {
const cekData = dataExport || []
if (cekData.length > 0) {
exportExcel()
}
}, [dataExport])
const getReferralCode = async () => {
let start = 0;
if (currentPage !== 1 && currentPage > 1) {
start = currentPage * rowsPerPage - rowsPerPage;
}
const payload = {
group_column: {
"operator": "AND",
"group_operator": "OR",
"where": [
{
"name": "name",
"logic_operator": "~*",
"value": search,
}
]
},
columns: [],
"orders": {
"ascending": true,
"columns": [
'id'
]
},
"paging": {
"length": rowsPerPage,
"start": start
},
'joins': []
}
const result = await axios
.post(REFERRAL_CODE_SEARCH, payload, HEADER)
.then(res => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
setDatatable(result.data.data);
setTotalPage(result.data.totalRecord);
setLoading(false)
} else {
NotificationManager.error('Gagal Mengambil Data!!', 'Failed');
setLoading(false)
}
}
const handleExportExcel = async () => {
let start = 0;
if (currentPage !== 1 && currentPage > 1) {
start = (currentPage * rowsPerPage) - rowsPerPage
}
const payload = {
group_column: {
"operator": "AND",
"group_operator": "OR",
"where": [
{
"name": "name",
"logic_operator": "~*",
"value": search,
}
]
},
"columns": [],
"orders": {
"ascending": true,
"columns": [
'id'
]
},
"paging": {
"length": rowsPerPage,
"start": start
},
'joins': []
}
const result = await axios
.post(REFERRAL_CODE_SEARCH, payload, HEADER)
.then(res => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
let resData = result.data.data;
const excelData = [];
resData.map((val, index) => {
let dataRow = {};
dataRow["Kode"] = val.code;
dataRow["Jumlah"] = val.amount;
dataRow["Kuota"] = val.allocation;
dataRow["Kadaluarsa"] = val.exp;
dataRow["Deskripsi"] = val.deskription;
excelData.push(dataRow)
})
await setDataExport(excelData)
} else {
NotificationManager.error('Gagal Export Data!!', 'Failed');
}
}
const exportExcel = () => {
const dataExcel = dataExport || [];
const fileName = `Data ${pageName}.xlsx`;
const ws = XLSX.utils.json_to_sheet(dataExcel);
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, `Data ${pageName}`);
XLSX.writeFile(wb, fileName);
setDataExport([])
}
const handleSearch = e => {
const value = e.target.value
setSearch(value);
setCurrentPage(1)
};
const handleOpenDialog = (type) => {
setOpenDialog(true)
setTypeDialog(type)
}
const handleEdit = (data) => {
setDataEdit(data)
handleOpenDialog('Edit');
}
const handleDelete = async (id) => {
await setAlertDelete(true)
await setIdDelete(id)
}
const handleCloseDialog = (type, data) => {
if (type === "save") {
saveReferralCode(data);
} else if (type === "edit") {
editReferralCode(data);
}
setDataEdit([])
setOpenDialog(false)
}
const saveReferralCode = async (data) => {
const formData = data
const result = await axios.post(REFERRAL_CODE_ADD, formData, HEADER)
.then(res => res)
.catch((error) => error.response);
if (result && result.data && result.data.code === 200) {
getReferralCode()
NotificationManager.success(`Data berhasil ditambahkan`, 'Success!!');
} else {
NotificationManager.error(`Data gagal ditambahkan`, 'Failed!!');
}
}
const editReferralCode = async (data) => {
let urlEdit = REFERRAL_CODE_EDIT(data.id)
const formData = data
const result = await axios.put(urlEdit, formData, HEADER)
.then(res => res)
.catch((error) => error.response);
if (result && result.data && result.data.code === 200) {
getReferralCode();
NotificationManager.success(`Data berhasil diubah`, 'Success!!');
} else {
NotificationManager.error(`Data gagal diubah`, `Failed!!`);
}
}
const toggleAddDialog = () => {
setOpenDialog(!openDialog)
}
const onConfirmDelete = async () => {
let url = REFERRAL_CODE_DELETE(idDelete);
const result = await axios.delete(url, HEADER)
.then(res => res)
.catch((error) => error.response);
if (result && result.data && result.data.code === 200) {
getReferralCode()
setIdDelete(0)
setAlertDelete(false)
NotificationManager.success(`Data berhasil dihapus!`, 'Success!!');
} else {
setIdDelete(0)
setAlertDelete(false)
NotificationManager.error(`Data gagal dihapus!}`, 'Failed!!');
}
}
const cancelDelete = () => {
setAlertDelete(false)
setIdDelete(0)
}
const onShowSizeChange = (current, pageSize) => {
setRowsPerPage(pageSize)
}
const onPagination = (current, pageSize) => {
setCurrentPage(current)
}
const dataNotAvailable = () => {
if (dataTable.length === 0) {
return (
<tr>
<td align="center" colSpan="7">{t('noData')}</td>
</tr>
)
}
}
return (
<div>
<NotificationContainer />
<SweetAlert
show={alertDelete}
warning
showCancel
confirmBtnText="Delete"
confirmBtnBsStyle="danger"
title={t('deleteConfirm')}
onConfirm={onConfirmDelete}
onCancel={cancelDelete}
focusCancelBtn
>
{t('deleteMsg')}
</SweetAlert>
<DialogForm
openDialog={openDialog}
closeDialog={handleCloseDialog}
toggleDialog={() => toggleAddDialog}
typeDialog={typeDialog}
dataEdit={dataEdit}
clickOpenModal={clickOpenModal}
dataParent={allDataMenu}
/>
<Card>
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}>
<h4 className="capitalize">{pageName}</h4>
<Row>
<Col>
<Input onChange={handleSearch} value={search} type="text" name="search" id="search" placeholder={t('search')} />
</Col>
<Col>
<Tooltip title={t('demoAdd')}>
<Button style={{ background: "#4caf50", color: "#fff" }} onClick={() => handleOpenDialog('Save')}><i className="fa fa-plus"></i></Button>
</Tooltip>
<Tooltip title={t('exportExcel')}>
<Button style={{ marginLeft: "5px" }} onClick={() => handleExportExcel()}><i className="fa fa-print"></i></Button>
</Tooltip>
</Col>
</Row>
</CardHeader>
<CardBody>
<Spin tip="Loading..." spinning={loading}>
<Table responsive striped hover>
<thead>
<tr>
<th>Aksi</th>
{column.map((i, index) => {
return (
<th key={index} scope="row">{i.name}</th>
)
})}
</tr>
</thead>
<tbody>
{dataNotAvailable()}
{dataTable.map((n, index) => {
return (
<tr key={n.id}>
<td className='nowrap'>
<Tooltip title={t('delete')}>
<i id="TooltipDelete" className="fa fa-trash" style={{ color: 'red', marginRight: 10, cursor: "pointer" }} onClick={() => handleDelete(n.id)}></i>
</Tooltip>
<Tooltip title={t('edit')}>
<i id="TooltipEdit" className="fa fa-edit" style={{ color: 'green', cursor: "pointer" }} onClick={() => handleEdit(n)}></i>
</Tooltip>
</td>
<td>{n.code}</td>
<td>{n.type}</td>
<td>{toRupiah(n.amount)}</td>
<td>{n?.exp ? moment(n.exp).format('DD-MM-YYYY HH:mm') : "-"}</td>
<td>{n.allocation ? n.allocation : "-"}</td>
<td>{n.description ? n.description : "-"}</td>
</tr>
)
})}
</tbody>
</Table>
</Spin>
</CardBody>
</Card>
</div>
)
}
export default ProjectType;

201
src/views/SimproV2/SalesContact/DialogForm.js

@ -0,0 +1,201 @@
import React, { useEffect, useState } from 'react'
import {
Modal, ModalHeader, ModalBody, ModalFooter,
Button, Form, FormGroup, Label, Input, Col, Row
} from 'reactstrap';
import { Select } from 'antd';
import 'antd/dist/antd.css';
import { useTranslation } from 'react-i18next';
import "rc-color-picker/assets/index.css";
const { Option } = Select
const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit }) => {
const [id, setId] = useState(0)
const [name, setName] = useState('')
const [email, setEmail] = useState('')
const [message, setMessage] = useState('')
const [phoneNumber, setPhoneNumber] = useState('')
const [role, setRole] = useState(null)
const [status, setStatus] = useState('')
const { t } = useTranslation()
useEffect(() => {
if (typeDialog === "Edit") {
setId(dataEdit.id)
setName(dataEdit.name)
setEmail(dataEdit.email)
setMessage(dataEdit.message)
setPhoneNumber(dataEdit.number_phone)
setStatus(dataEdit.status)
setRole(dataEdit.role)
} else {
setId(0)
setName('')
setEmail('')
setMessage('')
setStatus('')
setRole('')
setPhoneNumber('')
}
}, [dataEdit, openDialog])
const validation = () => {
if (!name || name === "") {
alert("Name cannot be empty!");
return true;
}
}
const handleSave = () => {
let data = '';
const err = validation();
if (!err) {
if (typeDialog === "Save") {
data = {
name,
email,
message,
number_phone: phoneNumber,
role,
status
}
closeDialog('save', data);
} else {
data = {
id,
name,
email,
message,
number_phone: phoneNumber,
role,
status
}
closeDialog('edit', data);
}
setId(0)
setName('')
}
}
const handleCancel = () => {
closeDialog('cancel', 'none')
setId(0)
setName('')
}
const onChangeStatus = (val) => {
setStatus(val)
}
const renderForm = () => {
return (
<Form>
<Row>
<Col md={12}>
<span style={{ color: "red" }}>*</span> Wajib diisi.
</Col>
</Row>
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize">{t('name')}<span style={{ color: "red" }}>*</span></Label>
<Input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder={t('inputName')}
/>
</FormGroup>
</Col>
<Col md={6}>
<FormGroup>
<Label className="capitalize">{t('email')}<span style={{ color: "red" }}>*</span></Label>
<Input
type="text"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder={t('inputEmail')}
/>
</FormGroup>
</Col>
</Row>
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize">{t('phoneNumber')}<span style={{ color: "red" }}>*</span></Label>
<Input
type="text"
value={phoneNumber}
onChange={(e) => setName(e.target.value)}
placeholder={t('inputNoPhone')}
/>
</FormGroup>
</Col>
<Col md={6}>
<FormGroup>
<Label className="capitalize">{t('role')}<span style={{ color: "red" }}>*</span></Label>
<Input
type="text"
value={role}
onChange={(e) => setRole(e.target.value)}
placeholder={t('inputRole')}
/>
</FormGroup>
</Col>
</Row>
<Row>
<Col md={12}>
<FormGroup>
<Label className="capitalize">
{t('status')}<span style={{ color: "red" }}>*</span>
</Label>
<Select
showSearch
filterOption={(inputValue, option) =>
option.children.toLowerCase().includes(inputValue.toLowerCase())
}
value={status}
defaultValue={status}
onChange={onChangeStatus}
style={{ width: "100%" }}
>
<Option value="New Contact">New Contact</Option>
<Option value="Presentation">Presentation</Option>
<Option value="Live Demo">Live Demo</Option>
<Option value="Trial">Trial</Option>
<Option value="Go-Live">Go-Live</Option>
<Option value="Postpone">Postpone</Option>
</Select>
</FormGroup>
</Col>
</Row>
<Row>
<Col md={12}>
<FormGroup>
<Label className="capitalize">{t('message')}</Label>
<Input row="4" type="textarea" value={message} onChange={(e) => setMessage(e.target.value)} placeholder={t('inputMessage')} />
</FormGroup>
</Col>
</Row>
</Form>
)
}
return (
<>
<Modal size="lg" isOpen={openDialog} toggle={toggleDialog}>
<ModalHeader className="capitalize" toggle={closeDialog}>{typeDialog == "Save" ? `Add` : "Edit"} {t('Demo')}</ModalHeader>
<ModalBody>
{renderForm()}
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={() => handleSave()}>{typeDialog}</Button>{' '}
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>{t('cancel')}</Button>
</ModalFooter>
</Modal>
</>
)
}
export default DialogForm;

374
src/views/SimproV2/SalesContact/index.js

@ -0,0 +1,374 @@
import * as XLSX from 'xlsx';
import DialogForm from './DialogForm';
import React, { useState, useEffect } from 'react';
import SweetAlert from 'react-bootstrap-sweetalert';
import axios from "../../../const/interceptorApi"
import { Card, CardBody, CardHeader, Col, Row, Input, Table } from 'reactstrap';
import { SALES_CONTACT_EDIT, SALES_CONTACT_SEARCH, SALES_CONTACT_LIST, SALES_CONTACT_GET_ID, SALES_CONTACT_ADD, SALES_CONTACT_DELETE } from '../../../const/ApiConst';
import { NotificationContainer, NotificationManager } from 'react-notifications';
import { Spin, Button, Tooltip } from 'antd';
import { useTranslation } from 'react-i18next';
const ProjectType = ({ params, ...props }) => {
let role_id = 0, user_id = 0, isLogin = false, token = '', company_id = 0, all_project = null, role_name = '', hierarchy = [], user_name = '';
if (props && props.role_id && props.user_id) {
role_id = props.role_id;
user_id = props.user_id;
token = props.token;
isLogin = props.isLogin;
company_id = props.company_id;
all_project = props.all_project;
role_name = props.role_name;
isLogin = props.isLogin;
hierarchy = props.hierarchy;
user_name = props.user_name;
}
const HEADER = {
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`
}
}
const pageName = params.name;
const [alertDelete, setAlertDelete] = useState(false)
const [allDataMenu, setAllDataMenu] = useState([])
const [clickOpenModal, setClickOpenModal] = useState(false)
const [currentPage, setCurrentPage] = useState(1)
const [dataEdit, setDataEdit] = useState([])
const [dataExport, setDataExport] = useState([])
const [dataTable, setDatatable] = useState([])
const [idDelete, setIdDelete] = useState(0)
const [openDialog, setOpenDialog] = useState(false)
const [rowsPerPage, setRowsPerPage] = useState(10)
const [search, setSearch] = useState("")
const [totalPage, setTotalPage] = useState(0)
const [typeDialog, setTypeDialog] = useState('Save')
const [dataDemo, setDataDemo] = useState([])
const [listCompany, setListCompany] = useState([])
const [loading, setLoading] = useState(true);
const { t } = useTranslation()
const column = [
{ name: t('name') },
{ name: t('company') },
{ name: t('email') },
{ name: t('roles') },
{ name: t('phoneNumber') },
{ name: t('status') },
{ name: t('description') },
].filter(column => column && column.name);
useEffect(() => {
getDataContactSales();
}, [currentPage, rowsPerPage, search])
useEffect(() => {
const cekData = dataExport || []
if (cekData.length > 0) {
exportExcel()
}
}, [dataExport])
const getDataContactSales = async () => {
let start = 0;
if (currentPage !== 1 && currentPage > 1) {
start = currentPage * rowsPerPage - rowsPerPage;
}
const payload = {
group_column: {
"operator": "AND",
"group_operator": "OR",
"where": [
{
"name": "name",
"logic_operator": "~*",
"value": search,
}
]
},
columns: [],
"orders": {
"ascending": true,
"columns": [
'id'
]
},
"paging": {
"length": rowsPerPage,
"start": start
},
'joins': []
}
const result = await axios
.post(SALES_CONTACT_SEARCH, payload, HEADER)
.then(res => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
setDatatable(result.data.data);
setTotalPage(result.data.totalRecord);
setLoading(false)
} else {
NotificationManager.error('Gagal Mengambil Data!!', 'Failed');
setLoading(false)
}
}
const handleExportExcel = async () => {
let start = 0;
if (currentPage !== 1 && currentPage > 1) {
start = (currentPage * rowsPerPage) - rowsPerPage
}
const payload = {
group_column: {
"operator": "AND",
"group_operator": "OR",
"where": [
{
"name": "name",
"logic_operator": "~*",
"value": search,
}
]
},
"columns": [],
"orders": {
"ascending": true,
"columns": [
'id'
]
},
"paging": {
"length": rowsPerPage,
"start": start
},
'joins': []
}
const result = await axios
.post(SALES_CONTACT_SEARCH, payload, HEADER)
.then(res => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
let resData = result.data.data;
const excelData = [];
resData.map((val, index) => {
let dataRow = {};
dataRow["Nama"] = val.name;
dataRow["Email"] = val.email;
dataRow["Role"] = val.role;
dataRow["No Telepon"] = val.number_phone;
dataRow["Status"] = val.message;
dataRow["Message"] = val.message;
excelData.push(dataRow)
})
await setDataExport(excelData)
} else {
NotificationManager.error('Gagal Export Data!!', 'Failed');
}
}
const exportExcel = () => {
const dataExcel = dataExport || [];
const fileName = `Data ${pageName}.xlsx`;
const ws = XLSX.utils.json_to_sheet(dataExcel);
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, `Data ${pageName}`);
XLSX.writeFile(wb, fileName);
setDataExport([])
}
const handleSearch = e => {
const value = e.target.value
setSearch(value);
setCurrentPage(1)
};
const handleOpenDialog = (type) => {
setOpenDialog(true)
setTypeDialog(type)
}
const handleEdit = (data) => {
setDataEdit(data)
handleOpenDialog('Edit');
}
const handleDelete = async (id) => {
await setAlertDelete(true)
await setIdDelete(id)
}
const handleCloseDialog = (type, data) => {
if (type === "save") {
saveContactSales(data);
} else if (type === "edit") {
editContactSales(data);
}
setDataEdit([])
setOpenDialog(false)
}
const saveContactSales = async (data) => {
const formData = data
const result = await axios.post(SALES_CONTACT_ADD, formData, HEADER)
.then(res => res)
.catch((error) => error.response);
if (result && result.data && result.data.code === 200) {
getDataContactSales()
NotificationManager.success(`Data berhasil ditambahkan`, 'Success!!');
} else {
NotificationManager.error(`Data gagal ditambahkan`, 'Failed!!');
}
}
const editContactSales = async (data) => {
let urlEdit = SALES_CONTACT_EDIT(data.id)
const formData = data
const result = await axios.put(urlEdit, formData, HEADER)
.then(res => res)
.catch((error) => error.response);
if (result && result.data && result.data.code === 200) {
getDataContactSales();
NotificationManager.success(`Data berhasil diubah`, 'Success!!');
} else {
NotificationManager.error(`Data gagal diubah`, `Failed!!`);
}
}
const toggleAddDialog = () => {
setOpenDialog(!openDialog)
}
const onConfirmDelete = async () => {
let url = SALES_CONTACT_DELETE(idDelete);
const result = await axios.delete(url, HEADER)
.then(res => res)
.catch((error) => error.response);
if (result && result.data && result.data.code === 200) {
getDataContactSales()
setIdDelete(0)
setAlertDelete(false)
NotificationManager.success(`Data berhasil dihapus!`, 'Success!!');
} else {
setIdDelete(0)
setAlertDelete(false)
NotificationManager.error(`Data gagal dihapus!}`, 'Failed!!');
}
}
const cancelDelete = () => {
setAlertDelete(false)
setIdDelete(0)
}
const onShowSizeChange = (current, pageSize) => {
setRowsPerPage(pageSize)
}
const onPagination = (current, pageSize) => {
setCurrentPage(current)
}
const dataNotAvailable = () => {
if (dataTable.length === 0) {
return (
<tr>
<td align="center" colSpan="8">{t('noData')}</td>
</tr>
)
}
}
return (
<div>
<NotificationContainer />
<SweetAlert
show={alertDelete}
warning
showCancel
confirmBtnText="Delete"
confirmBtnBsStyle="danger"
title={t('deleteConfirm')}
onConfirm={onConfirmDelete}
onCancel={cancelDelete}
focusCancelBtn
>
{t('deleteMsg')}
</SweetAlert>
<DialogForm
openDialog={openDialog}
closeDialog={handleCloseDialog}
toggleDialog={() => toggleAddDialog}
typeDialog={typeDialog}
dataEdit={dataEdit}
clickOpenModal={clickOpenModal}
dataParent={allDataMenu}
/>
<Card>
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}>
<h4 className="capitalize">{pageName}</h4>
<Row>
<Col>
<Input onChange={handleSearch} value={search} type="text" name="search" id="search" placeholder={t('searchDemo')} />
</Col>
<Col>
<Tooltip title={t('demoAdd')}>
<Button style={{ background: "#4caf50", color: "#fff" }} onClick={() => handleOpenDialog('Save')}><i className="fa fa-plus"></i></Button>
</Tooltip>
<Tooltip title={t('exportExcel')}>
<Button style={{ marginLeft: "5px" }} onClick={() => handleExportExcel()}><i className="fa fa-print"></i></Button>
</Tooltip>
</Col>
</Row>
</CardHeader>
<CardBody>
<Spin tip="Loading..." spinning={loading}>
<Table responsive striped hover>
<thead>
<tr>
<th>Aksi</th>
{column.map((i, index) => {
return (
<th key={index} scope="row">{i.name}</th>
)
})}
</tr>
</thead>
<tbody>
{dataNotAvailable()}
{dataTable.map((n, index) => {
return (
<tr key={n.id}>
<td className='nowrap'>
<Tooltip title={t('delete')}>
<i id="TooltipDelete" className="fa fa-trash" style={{ color: 'red', marginRight: 10, cursor: "pointer" }} onClick={() => handleDelete(n.id)}></i>
</Tooltip>
<Tooltip title={t('edit')}>
<i id="TooltipEdit" className="fa fa-edit" style={{ color: 'green', cursor: "pointer" }} onClick={() => handleEdit(n)}></i>
</Tooltip>
</td>
<td>{n.name}</td>
<td>{n.company_name}</td>
<td>{n.email}</td>
<td>{n.role}</td>
<td>{n.number_phone}</td>
<td>{n.status}</td>
<td>{n.message}</td>
</tr>
)
})}
</tbody>
</Table>
</Spin>
</CardBody>
</Card>
</div>
)
}
export default ProjectType;
Loading…
Cancel
Save