farhantock
1 year ago
35 changed files with 5822 additions and 171 deletions
@ -1,20 +1,22 @@
|
||||
FROM node:12 |
||||
# Stage 1 |
||||
FROM node:14 as build-stage |
||||
|
||||
WORKDIR /react-docker |
||||
COPY ./package*.json ./ |
||||
ENV PATH /app/node_modules/.bin:$PATH |
||||
COPY package.json . |
||||
RUN npm install |
||||
RUN npm i react@16.14.0 |
||||
RUN npm i react-scripts |
||||
RUN npm audit fix |
||||
COPY . . |
||||
|
||||
#ARG REACT_APP_API_BASE_URL |
||||
#ENV REACT_APP_API_BASE_URL=$REACT_APP_API_BASE_URL |
||||
|
||||
EXPOSE 8445 |
||||
RUN npm run build |
||||
|
||||
# Comment as needed (Production / Dev) |
||||
# [PROD] Use for Production |
||||
# COPY . . # uncomment prod |
||||
# Stage 2 |
||||
#FROM nginx:1.17.0-alpine |
||||
FROM nginx:alpine |
||||
|
||||
# [DEV] Live Reload |
||||
RUN mkdir -p /react-docker/src # comment for prod |
||||
RUN mkdir -p /react-docker/public # comment for prod |
||||
COPY --from=build-stage /react-docker/build /usr/share/nginx/html |
||||
COPY nginx/nginx.conf /etc/nginx/conf.d/default.conf |
||||
EXPOSE 80 |
||||
|
||||
CMD PORT=8445 npm start #--host 0.0.0.0 --port 3000 --disableHostCheck true |
||||
CMD nginx -g 'daemon off;' |
||||
|
@ -0,0 +1,17 @@
|
||||
server { |
||||
|
||||
listen 80; |
||||
|
||||
location / { |
||||
root /usr/share/nginx/html; |
||||
index index.html index.htm; |
||||
try_files $uri $uri/ /index.html; |
||||
} |
||||
|
||||
error_page 500 502 503 504 /50x.html; |
||||
|
||||
location = /50x.html { |
||||
root /usr/share/nginx/html; |
||||
} |
||||
|
||||
} |
After Width: | Height: | Size: 54 KiB |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,822 @@
|
||||
import React, { useState, useMemo, useEffect } from 'react' |
||||
import { |
||||
Modal, ModalHeader, ModalBody, ModalFooter, |
||||
Button, Form, FormGroup, Row, Col, Label, Input, |
||||
} from 'reactstrap'; |
||||
import { Pagination, Table, Tooltip, Select } from 'antd'; |
||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import DialogFormUser from './FormUser'; |
||||
import DialogFormMenu from './FormMenu'; |
||||
import 'antd/dist/antd.css'; |
||||
import { useTranslation } from 'react-i18next'; |
||||
import axios from "../../../const/interceptorApi" |
||||
import { |
||||
USER_SEARCH, USER_EDIT, USER_DELETE, ROLE_SEARCH, DIVISI_SEARCH, MENU_COMPANY_SEARCH |
||||
} from '../../../const/ApiConst'; |
||||
const token = window.localStorage.getItem('token'); |
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, companyID, companyNameProp }) => { |
||||
const { Option } = Select |
||||
const { t } = useTranslation() |
||||
const [registrationnumber, setRegistrationNumber] = useState('') |
||||
const [companyName, setCompanyName] = useState('') |
||||
const [addressCompany, setAddressCompany] = useState('') |
||||
const [phoneNumber, setPhoneNumber] = useState('') |
||||
const [emailCompany, setEmailCompany] = useState('') |
||||
const [description, setDescription] = useState('') |
||||
const [logoLogin, setLogoLogin] = useState([]) |
||||
const [logoHeader, setLogoHeader] = useState([]) |
||||
const [favIcon, setFavIcon] = useState([]) |
||||
const [loginInstruction, setLoginInstruction] = useState('') |
||||
const [about, setAbout] = useState('') |
||||
const [htmlTitle, setHtmlTitle] = useState('') |
||||
const [appName, setAppName] = useState('') |
||||
const [baseUrl, setBaseUrl] = useState([]) |
||||
const [statusCompany, setStatusCompany] = useState(true) |
||||
const [template, setTemplate] = useState('') |
||||
const [lastIdxURL, setLastIdxURL] = useState(0); |
||||
|
||||
|
||||
const [dataTable, setDatatable] = useState([]) |
||||
const [openDialogUser, setOpenDialogUser] = useState(false) |
||||
const [typeDialogUser, setTypeDialogUser] = useState("add") |
||||
const [currentPage, setCurrentPage] = useState(1) |
||||
const [rowsPerPage, setRowsPerPage] = useState(10) |
||||
const [totalPage, setTotalPage] = useState(0) |
||||
const [search, setSearch] = useState('') |
||||
const [idDelete, setIdDelete] = useState(0) |
||||
const [alertDelete, setAlertDelete] = useState(false) |
||||
const [dataEdit, setDataEdit] = useState([]) |
||||
const [roleList, setRoleList] = useState([]) |
||||
|
||||
|
||||
const [dataTableMenu, setDatatableMenu] = useState([]) |
||||
const [currentPageMenu, setCurrentPageMenu] = useState(1) |
||||
const [rowsPerPageMenu, setRowsPerPageMenu] = useState(10) |
||||
const [totalPageMenu, setTotalPageMenu] = useState(0) |
||||
const [openDialogMenu, setOpenDialogMenu] = useState(false) |
||||
const [typeDialogMenu, setTypeDialogMenu] = useState("add") |
||||
useEffect(() => { |
||||
if (companyID && typeDialog === 'Set') { |
||||
getDataUser() |
||||
getRoleList() |
||||
} else { |
||||
getDataMenu() |
||||
} |
||||
}, [typeDialog, companyID, rowsPerPage, currentPage, rowsPerPageMenu, currentPageMenu]) |
||||
|
||||
|
||||
const onShowSizeChange = (current, pageSize) => { |
||||
setRowsPerPage(pageSize) |
||||
} |
||||
|
||||
const onPagination = (current, pageSize) => { |
||||
setCurrentPage(current) |
||||
} |
||||
const onShowSizeChangeMenu = (current, pageSize) => { |
||||
setRowsPerPageMenu(pageSize) |
||||
} |
||||
|
||||
const onPaginationMenu = (current, pageSize) => { |
||||
setCurrentPageMenu(current) |
||||
} |
||||
|
||||
const getRoleList = async () => { |
||||
const formData = { |
||||
"paging": { "start": 0, "length": -1 }, |
||||
|
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(ROLE_SEARCH, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
setRoleList(result.data.data); |
||||
} |
||||
} |
||||
|
||||
const getDataUser = async () => { |
||||
let start = 0; |
||||
|
||||
if (currentPage !== 1 && currentPage > 1) { |
||||
start = (currentPage * rowsPerPage) - rowsPerPage |
||||
} |
||||
|
||||
const payload = { |
||||
"paging": { |
||||
"start": start, |
||||
"length": rowsPerPage |
||||
}, |
||||
"columns": [], |
||||
"group_column": { |
||||
"operator": "AND", |
||||
"group_operator": "OR", |
||||
"where": [ |
||||
{ |
||||
"name": "name", |
||||
"logic_operator": "~*", |
||||
"value": search |
||||
}, |
||||
{ |
||||
"name": "ktp_number", |
||||
"logic_operator": "~*", |
||||
"value": search |
||||
}, |
||||
{ |
||||
"name": "name", |
||||
"logic_operator": "~*", |
||||
"value": search, |
||||
"table_name": "m_divisi" |
||||
}, |
||||
{ |
||||
"name": "employee_type", |
||||
"logic_operator": "~*", |
||||
"value": search |
||||
}, |
||||
{ |
||||
"name": "name", |
||||
"logic_operator": "~*", |
||||
"value": search, |
||||
"table_name": "m_roles" |
||||
}, |
||||
{ |
||||
"name": "phone_number", |
||||
"logic_operator": "~*", |
||||
"value": search |
||||
}, |
||||
{ |
||||
"name": "email", |
||||
"logic_operator": "~*", |
||||
"value": search |
||||
}, |
||||
{ |
||||
"name": "status_resource", |
||||
"logic_operator": "~*", |
||||
"value": search |
||||
}, |
||||
{ |
||||
"name": "company_id", |
||||
"logic_operator": "=", |
||||
"value": companyID |
||||
}, |
||||
] |
||||
}, |
||||
"joins": [ |
||||
{ |
||||
"name": "m_roles", |
||||
"column_join": "role_id", |
||||
"column_results": [ |
||||
"name", |
||||
"description" |
||||
] |
||||
}, |
||||
{ |
||||
"name": "m_divisi", |
||||
"column_join": "divisi_id", |
||||
"column_results": [ |
||||
"name" |
||||
] |
||||
} |
||||
], |
||||
"orders": { |
||||
"columns": [ |
||||
"id" |
||||
], |
||||
"ascending": false |
||||
} |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(USER_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
setDatatable(result.data.data); |
||||
setTotalPage(result.data.totalRecord); |
||||
} else { |
||||
NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
const getDataMenu = async () => { |
||||
let start = 0; |
||||
|
||||
if (currentPage !== 1 && currentPage > 1) { |
||||
start = (currentPage * rowsPerPage) - rowsPerPage |
||||
} |
||||
|
||||
const payload = { |
||||
"paging": { |
||||
"start": start, |
||||
"length": rowsPerPage |
||||
}, |
||||
"columns": [{ |
||||
"name": "company_id", |
||||
"logic_operator": "=", |
||||
"value": companyID, |
||||
"operator": "AND" |
||||
}], |
||||
"joins": [{ |
||||
"name": "m_menu", |
||||
"column_join": "menu_id", |
||||
"column_results": [ |
||||
"name" |
||||
] |
||||
}], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(MENU_COMPANY_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
setDatatableMenu(result.data.data); |
||||
setTotalPageMenu(result.data.totalRecord); |
||||
} else { |
||||
NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
|
||||
const handleAddUser = async () => { |
||||
await setTypeDialogUser("Save") |
||||
setOpenDialogUser(true) |
||||
} |
||||
|
||||
const handleEditUser = async (data) => { |
||||
setDataEdit(data) |
||||
await setTypeDialogUser('Edit') |
||||
setOpenDialogUser(true) |
||||
} |
||||
const handleDeleteUser = async (id) => { |
||||
await setAlertDelete(true) |
||||
await setIdDelete(id) |
||||
} |
||||
|
||||
const closeDialogUser = (type, message) => { |
||||
setOpenDialogUser(false); |
||||
if (type == 'success') { |
||||
NotificationManager.success(`${message}`, "Success!!"); |
||||
getDataUser() |
||||
} else if (type == 'Failed') { |
||||
NotificationManager.error(`${message}`, "Failed!!"); |
||||
} |
||||
}; |
||||
|
||||
const handleAddMenu = async () => { |
||||
await setTypeDialogMenu("Save") |
||||
setOpenDialogMenu(true) |
||||
} |
||||
|
||||
const handleEditMenu = async (data) => { |
||||
setDataEdit(data) |
||||
await setTypeDialogMenu('Edit') |
||||
setOpenDialogMenu(true) |
||||
} |
||||
|
||||
const handleDeleteMenu = async (id) => { |
||||
await setAlertDelete(true) |
||||
await setIdDelete(id) |
||||
} |
||||
|
||||
const closeDialogMenu = (type, message) => { |
||||
setOpenDialogMenu(false); |
||||
if (type == 'success') { |
||||
NotificationManager.success(`${message}`, "Success!!"); |
||||
getDataMenu() |
||||
} else if (type == 'Failed') { |
||||
NotificationManager.error(`${message}`, "Failed!!"); |
||||
} |
||||
|
||||
}; |
||||
|
||||
const handleSave = () => { |
||||
let data = ''; |
||||
|
||||
if (!registrationnumber && registrationnumber === "") { |
||||
alert("Please input Registration Number"); |
||||
return; |
||||
} |
||||
if (!companyName && companyName === "") { |
||||
alert("Please input the name"); |
||||
return; |
||||
} |
||||
|
||||
if (typeDialog === "Save") { |
||||
data = { |
||||
registration_no: registrationnumber, |
||||
company_name: companyName, |
||||
address: addressCompany, |
||||
phone_no: phoneNumber, |
||||
email: emailCompany, |
||||
description: description, |
||||
logo_login: logoLogin, |
||||
logo_header: logoHeader, |
||||
favicon_image: favIcon, |
||||
login_instruction: loginInstruction, |
||||
about: about, |
||||
html_title: htmlTitle, |
||||
app_name: appName, |
||||
base_url: baseUrl, |
||||
is_active: statusCompany, |
||||
template_id: template |
||||
} |
||||
console.log(data) |
||||
|
||||
closeDialog('save', data); |
||||
} else if (typeDialog === "Set") { |
||||
// if (!password && password === "") {
|
||||
// alert("Please fill password");
|
||||
// return;
|
||||
// }
|
||||
// if (password !== retryPassword) {
|
||||
// alert("Password doesn't match");
|
||||
// return;
|
||||
// }
|
||||
// if (password.length < 8) {
|
||||
// alert("Password minimum 8 character");
|
||||
// return;
|
||||
// }
|
||||
// data = {
|
||||
// id,
|
||||
// username,
|
||||
// password,
|
||||
// email,
|
||||
// }
|
||||
|
||||
closeDialog('edit', data); |
||||
} else { |
||||
|
||||
// data = {
|
||||
// id,
|
||||
// name: resourceName,
|
||||
// username,
|
||||
// employee_type: employeeType,
|
||||
// phone_number: phoneNo,
|
||||
// email,
|
||||
// gender,
|
||||
// birth_place: birthPlace,
|
||||
// blood_type: bloodType,
|
||||
// ktp_number: ktpNumber,
|
||||
// biaya_per_jam: biayaPerJam.replace('.', ''),
|
||||
// role_id: roleId,
|
||||
// divisi_id: divisionId,
|
||||
// address,
|
||||
// status_resource: statusResource,
|
||||
// status_boundary: statusRestriction,
|
||||
// company_id: company_id
|
||||
// }
|
||||
|
||||
// if (birthDate && birthDate != "") {
|
||||
// data['birth_date'] = birthDate;
|
||||
// }
|
||||
|
||||
closeDialog('edit', data); |
||||
} |
||||
} |
||||
|
||||
const isValidEmail = (email) => { |
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; |
||||
return emailRegex.test(email); |
||||
}; |
||||
|
||||
const handleCancel = () => { |
||||
closeDialog('cancel', 'none') |
||||
setDatatable([]) |
||||
} |
||||
|
||||
const onConfirmDelete = async () => { |
||||
let url = USER_DELETE(idDelete); |
||||
|
||||
const result = await axios.delete(url, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataUser() |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.success(`Data user berhasil dihapus!`, 'Success!!'); |
||||
} else { |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.error(`Data user gagal dihapus!`, 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
const cancelDelete = () => { |
||||
setAlertDelete(false) |
||||
setIdDelete(0) |
||||
} |
||||
|
||||
const addBaseUrl = () => { |
||||
baseUrl.push({ |
||||
id: lastIdxURL + 1, |
||||
url: "", |
||||
}); |
||||
setBaseUrl(baseUrl); |
||||
setLastIdxURL(lastIdxURL + 1); |
||||
}; |
||||
|
||||
const handleChangeBaseURL = (value, index) => { |
||||
const newBaseURL = [...baseUrl]; |
||||
newBaseURL[index] = value; |
||||
setBaseUrl(newBaseURL); |
||||
} |
||||
|
||||
const deleteBaseURL = (id) => { |
||||
if (baseUrl && baseUrl.length > 0) { |
||||
let checkIdx = baseUrl.findIndex((o) => o.id === id); |
||||
if (checkIdx > -1) { |
||||
baseUrl.splice(checkIdx, 1); |
||||
setBaseUrl(baseUrl.filter((_, i2) => i2 !== id)); |
||||
} |
||||
} |
||||
} |
||||
|
||||
const handleLogoHeader = (content) => { |
||||
const newLogoHeader = [...logoHeader, { |
||||
type: "image", |
||||
content: content, |
||||
}]; |
||||
setLogoHeader(newLogoHeader); |
||||
} |
||||
|
||||
const RenderBaseURL = () => { |
||||
if (baseUrl.length > 0) { |
||||
return baseUrl.map((item, index) => { |
||||
return ( |
||||
<Row key={index} style={{ marginBottom: 10 }}> |
||||
<Col md={8}> |
||||
<Input |
||||
type="text" |
||||
value={item.url} |
||||
name="item" |
||||
onChange={(e) => handleChangeBaseURL(e, index)} |
||||
/> |
||||
</Col> |
||||
<Col md={2}> |
||||
<Button |
||||
color="danger" |
||||
size="sm" |
||||
onClick={() => deleteBaseURL(item.id)} |
||||
> |
||||
<i className="fa fa-trash"></i> |
||||
</Button> |
||||
</Col> |
||||
</Row> |
||||
); |
||||
}); |
||||
} else if (baseUrl.length < 1) { |
||||
return ( |
||||
<div |
||||
style={{ |
||||
textAlign: "center", |
||||
color: "red", |
||||
marginTop: 25, |
||||
marginBottom: 25, |
||||
}} |
||||
> |
||||
No Base URL found |
||||
</div> |
||||
); |
||||
} |
||||
}; |
||||
|
||||
|
||||
const renderFromCompany = () => { |
||||
return ( |
||||
<Form> |
||||
<Row> |
||||
<Col md={12}> |
||||
<span style={{ color: "red" }}>*</span>required. |
||||
</Col> |
||||
</Row> |
||||
<Row> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">Number Registration<span style={{ color: "red" }}>*</span></Label> |
||||
<Input type="text" value={registrationnumber} onChange={(e) => setRegistrationNumber(e.target.value)} placeholder='Input Number Registration' /> |
||||
</FormGroup> |
||||
</Col> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">Company Name<span style={{ color: "red" }}>*</span></Label> |
||||
<Input type="text" value={companyName} onChange={(e) => setCompanyName(e.target.value)} placeholder=' Input Company Name' /> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
<Row> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">Email</Label> |
||||
<Input type="email" value={emailCompany} onChange={(e) => setEmailCompany(e.target.value)} placeholder={t('inputEmail')} |
||||
onBlur={(e) => { |
||||
if (!isValidEmail(e.target.value)) { |
||||
alert("Masukkan email yang valid."); |
||||
} |
||||
}} |
||||
/> |
||||
</FormGroup> |
||||
</Col> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">Phone Number</Label> |
||||
<Input type="text" value={phoneNumber} onChange={(e) => setPhoneNumber(e.target.value.replace(/[^0-9]/g, ''))} placeholder={t('inputNoPhone')} maxLength="15" /> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
<Row> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">Address</Label> |
||||
<Input type="textarea" value={addressCompany} onChange={(e) => setAddressCompany(e.target.value)} placeholder=' Input Address' /> |
||||
</FormGroup> |
||||
</Col> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">About</Label> |
||||
<Input type="textarea" value={about} onChange={(e) => setAbout(e.target.value)} placeholder=' Input Company Name' /> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
<Row> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">App Name</Label> |
||||
<Input type="text" value={appName} onChange={(e) => setAppName(e.target.value)} placeholder=' Input App Name' /> |
||||
</FormGroup> |
||||
</Col> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">HTML Title</Label> |
||||
<Input type="text" value={htmlTitle} onChange={(e) => setHtmlTitle(e.target.value)} placeholder=' Input HTML Title' /> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
<Row> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">Status Company<span style={{ color: "red" }}>*</span></Label> |
||||
<Select style={{ width: "100%" }} defaultValue={statusCompany} onChange={(e) => setStatusCompany(e)} placeholder="Select a template for application"> |
||||
<Option value={true}>Active</Option> |
||||
<Option value={false}>Inactive</Option> |
||||
</Select> |
||||
</FormGroup> |
||||
</Col> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">Template Application<span style={{ color: "red" }}>*</span></Label> |
||||
<Select style={{ width: "100%" }} defaultValue={template} onChange={(e) => setTemplate(e)} placeholder="Select a template for application"> |
||||
<Option value={'1'}>Construction</Option> |
||||
<Option value={'2'}>IT (Information AND Technology)</Option> |
||||
</Select> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
<Row> |
||||
<Col md={6}> |
||||
<Col md={12}> |
||||
<Label className="capitalize">Base URL<span style={{ color: "red" }}>*</span></Label> |
||||
<Row> |
||||
<Col md={8}> |
||||
<p>URL</p> |
||||
</Col> |
||||
<Col md={2}> |
||||
<p>Action</p> |
||||
</Col> |
||||
<Col md={1}> |
||||
<Tooltip title="Add row"> |
||||
<Button |
||||
size="sm" |
||||
color="primary" |
||||
onClick={() => addBaseUrl()} |
||||
> |
||||
<i className="fa fa-plus"></i> |
||||
</Button> |
||||
</Tooltip> |
||||
</Col> |
||||
</Row> |
||||
<div style={{ marginBottom: 50 }}>{RenderBaseURL()}</div> |
||||
</Col> |
||||
</Col> |
||||
<Col md={6}> |
||||
<Row> |
||||
<FormGroup> |
||||
<Label className="capitalize" style={{ fontWeight: "bold" }}>Logo Login</Label> |
||||
<Input |
||||
type="file" |
||||
accept="image/*" |
||||
// onChange={(e) => handleLogoHeader(e.target.files[0])}
|
||||
/> |
||||
</FormGroup> |
||||
</Row> |
||||
<Row> |
||||
<FormGroup> |
||||
<Label className="capitalize" style={{ fontWeight: "bold" }}>Logo Header</Label> |
||||
<Input |
||||
type="file" |
||||
accept="image/*" |
||||
onChange={(e) => handleLogoHeader(e.target.files[0])} |
||||
/> |
||||
</FormGroup> |
||||
</Row> |
||||
<Row> |
||||
<FormGroup> |
||||
<Label className="capitalize" style={{ fontWeight: "bold" }}>Fav Icon Logo</Label> |
||||
<Input |
||||
type="file" |
||||
accept="image/*" |
||||
// onChange={(e) => setProjectStructureOrg(e.target.files[0])}
|
||||
/> |
||||
</FormGroup> |
||||
</Row> |
||||
</Col> |
||||
</Row> |
||||
</Form> |
||||
) |
||||
} |
||||
|
||||
|
||||
|
||||
const RenderTableUser = useMemo(() => { |
||||
const columns = [ |
||||
{ |
||||
title: t('action'), |
||||
dataIndex: '', |
||||
key: 'x', |
||||
render: (text, record) => <> |
||||
<Tooltip title={t('edit')}> |
||||
<Button size={"sm"} color='success' onClick={() => handleEditUser(text)}><i className="fa fa-edit"></i></Button> |
||||
</Tooltip>{" "} |
||||
<Tooltip title={t('delete')}> |
||||
<Button size={"sm"} color='danger' onClick={() => handleDeleteUser(text.id)}><i className="fa fa-trash"></i></Button> |
||||
</Tooltip> |
||||
</>, |
||||
}, |
||||
|
||||
{ title: t('nik'), dataIndex: 'ktp_number', key: 'ktp_number' }, |
||||
{ title: t('nameHR'), dataIndex: 'name', key: 'name' }, |
||||
|
||||
{ title: t('employeeType'), dataIndex: 'employee_type', key: 'employee_type' }, |
||||
{ |
||||
title: t('roles'), |
||||
dataIndex: 'join_first_name', |
||||
key: 'join_first_name', |
||||
render: (text, record) => <>{record.join_first_name}</> |
||||
}, |
||||
{ title: 'Phone No.', dataIndex: 'phone_number', key: 'phone_number' }, |
||||
{ title: 'Email', dataIndex: 'email', key: 'email' }, |
||||
{ title: 'Status', dataIndex: 'status_resource', key: 'status_status' } |
||||
]; |
||||
return ( |
||||
<Table |
||||
rowKey="id" |
||||
size="small" |
||||
columns={columns} |
||||
dataSource={dataTable} |
||||
pagination={false} |
||||
/> |
||||
) |
||||
}, [dataTable]) |
||||
|
||||
|
||||
const renderTableMenu = useMemo(() => { |
||||
const columns = [ |
||||
{ |
||||
title: t('action'), |
||||
dataIndex: '', |
||||
key: 'x', |
||||
render: (text, record) => <> |
||||
<Tooltip title={t('delete')}> |
||||
<i id="TooltipDelete" className="fa fa-trash" style={{ color: 'red', marginRight: '10px', cursor: "pointer" }} onClick={() => handleDeleteMenu(text.id)}></i> |
||||
</Tooltip> |
||||
<Tooltip title={t('edit')}> |
||||
<i id="TooltipEdit" className="fa fa-edit" style={{ color: 'green', cursor: "pointer" }} onClick={() => handleEditMenu(text)}></i> |
||||
</Tooltip> |
||||
</>, |
||||
}, |
||||
{ title: t('name'), dataIndex: 'join_first_name', key: 'join_first_name' }, |
||||
{ title: 'Url', dataIndex: 'url', key: 'url' }, |
||||
{ title: t('icon'), dataIndex: 'icon', key: 'icon' }, |
||||
{ title: 'Alias', dataIndex: 'alias_name', key: 'alias_name' }, |
||||
{ title: t('order'), dataIndex: 'sequence', key: 'sequence' }, |
||||
{ title: t('parentMenu'), dataIndex: 'join_first_name', key: 'join_first_name', render: (text, record) => (text ? text : "-") } |
||||
]; |
||||
return ( |
||||
<Table |
||||
rowKey="id" |
||||
size="small" |
||||
columns={columns} |
||||
dataSource={dataTableMenu} |
||||
pagination={false} |
||||
/> |
||||
) |
||||
}, [dataTableMenu]) |
||||
|
||||
return ( |
||||
<> |
||||
<NotificationContainer /> |
||||
<SweetAlert |
||||
show={alertDelete} |
||||
warning |
||||
showCancel |
||||
confirmBtnText="Delete" |
||||
confirmBtnBsStyle="danger" |
||||
title={t('deleteConfirm')} |
||||
onConfirm={onConfirmDelete} |
||||
onCancel={() => cancelDelete()} |
||||
focusCancelBtn |
||||
> |
||||
{t('deleteMsg')} |
||||
</SweetAlert> |
||||
<DialogFormUser |
||||
openDialog={openDialogUser} |
||||
closeDialog={closeDialogUser} |
||||
typeDialog={typeDialogUser} |
||||
roleList={roleList} |
||||
companyID={companyID} |
||||
dataEdit={dataEdit} |
||||
/> |
||||
<DialogFormMenu |
||||
openDialog={openDialogMenu} |
||||
closeDialog={closeDialogMenu} |
||||
typeDialog={typeDialogMenu} |
||||
companyID={companyID} |
||||
companyName={companyNameProp} |
||||
dataEdit={dataEdit} |
||||
/> |
||||
<Modal size="xl" fullscreen="xl" scrollable={true} isOpen={openDialog} toggle={toggleDialog}> |
||||
<ModalHeader className="capitalize withBtn" toggle={closeDialog} style={{ width: "100%" }}> |
||||
{typeDialog === "Set-Menu" ? `Menu ${companyNameProp}` : typeDialog === "Save" ? `Add Data Company` : typeDialog === "Set" ? `Manage User ${companyNameProp}` : `Edit ${companyNameProp}`} |
||||
{typeDialog === "Set" ? ( |
||||
<Tooltip title="Add User"> |
||||
<Button onClick={handleAddUser} size='sm' color="primary"><i className='fa fa-plus'></i></Button> |
||||
</Tooltip> |
||||
) : |
||||
( |
||||
<Tooltip title="Add Menu"> |
||||
<Button onClick={handleAddMenu} size='sm' color="primary"><i className='fa fa-plus'></i></Button> |
||||
</Tooltip> |
||||
)} |
||||
</ModalHeader> |
||||
<ModalBody> |
||||
|
||||
{typeDialog !== "Set" && typeDialog !== "Set-Menu" && renderFromCompany()} |
||||
{typeDialog === "Set" && ( |
||||
<> |
||||
{RenderTableUser} |
||||
<Pagination |
||||
style={{ marginTop: "25px" }} |
||||
showSizeChanger |
||||
onShowSizeChange={onShowSizeChange} |
||||
onChange={onPagination} |
||||
pageSizeOptions={["10", "25", "50"]} |
||||
total={totalPage} |
||||
pageSize={rowsPerPage} |
||||
current={currentPage} |
||||
/> |
||||
</> |
||||
)} |
||||
{typeDialog === "Set-Menu" && ( |
||||
<> |
||||
{renderTableMenu} |
||||
<Pagination |
||||
style={{ marginTop: "25px" }} |
||||
showSizeChanger |
||||
onShowSizeChange={onShowSizeChangeMenu} |
||||
onChange={onPaginationMenu} |
||||
pageSizeOptions={["10", "25", "50"]} |
||||
total={totalPageMenu} |
||||
pageSize={rowsPerPageMenu} |
||||
current={currentPageMenu} |
||||
/> |
||||
</> |
||||
)} |
||||
|
||||
</ModalBody> |
||||
<ModalFooter> |
||||
{typeDialog !== "Set" && typeDialog !== "Set-Menu" && ( |
||||
<Button color="primary" onClick={() => handleSave()}>{typeDialog}</Button> |
||||
)} |
||||
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>cancel</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
</> |
||||
) |
||||
|
||||
} |
||||
export default DialogForm; |
@ -0,0 +1,285 @@
|
||||
import React, { useState, useEffect } from 'react' |
||||
import { |
||||
Modal, ModalHeader, ModalBody, ModalFooter, |
||||
Button, Form, FormGroup, Label, Input, Col, Row |
||||
} from 'reactstrap'; |
||||
import { Transfer, Select } from 'antd'; |
||||
import 'antd/dist/antd.css'; |
||||
import { useTranslation } from 'react-i18next'; |
||||
import { MENU_LIST, MENU_COMPANY_ADD, MENU_COMPANY_EDIT } from '../../../const/ApiConst.js'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import axios from 'axios'; |
||||
const token = window.localStorage.getItem('token'); |
||||
const FormMenu = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit, companyName, companyID }) => { |
||||
const { Option } = Select |
||||
const [targetKeys, setTargetKeys] = useState([]) |
||||
const [menuResource, setmenuResource] = useState([]) |
||||
const [id, setId] = useState(0) |
||||
const [name, setName] = useState('') |
||||
const [url, setUrl] = useState('') |
||||
const [aliasName, setAliasName] = useState('') |
||||
const [icon, setIcon] = useState('') |
||||
const [sequence, setSequence] = useState(0) |
||||
const [parentId, setParentId] = useState(null) |
||||
const { t } = useTranslation() |
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
|
||||
const handleCLearData = () => { |
||||
// setId(0)
|
||||
setTargetKeys([]) |
||||
} |
||||
|
||||
useEffect(() => { |
||||
if (!openDialog) { |
||||
handleCLearData() |
||||
} else { |
||||
getDataAllMenu(); |
||||
} |
||||
}, [openDialog]) |
||||
|
||||
const getDataAllMenu = async () => { |
||||
const result = await axios |
||||
.get(MENU_LIST, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
setTransferMenu(result.data.data); |
||||
} else { |
||||
NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
const setTransferMenu = (data) => { |
||||
const finalData = [] |
||||
data.map((val, index) => { |
||||
let data = { |
||||
key: val.id, |
||||
name: val.name, |
||||
url: val.url, |
||||
alias_name: val.alias_name, |
||||
icon: val.icon, |
||||
parent_id: val.parent_id, |
||||
sequence: val.sequence, |
||||
} |
||||
finalData.push(data) |
||||
}); |
||||
setmenuResource(finalData) |
||||
} |
||||
|
||||
|
||||
const handleSave = async () => { |
||||
await saveMenuCompany() |
||||
handleCLearData() |
||||
} |
||||
|
||||
useEffect(() => { |
||||
if (typeDialog === "Edit") { |
||||
setId(dataEdit.id) |
||||
setIcon(dataEdit.icon) |
||||
setParentId(dataEdit.parent_id) |
||||
setSequence(dataEdit.sequence) |
||||
} else { |
||||
setId(0) |
||||
setName('') |
||||
setUrl('') |
||||
setIcon('') |
||||
setParentId(null) |
||||
setSequence(0) |
||||
setAliasName('') |
||||
} |
||||
}, [dataEdit, openDialog]) |
||||
|
||||
const validation = () => { |
||||
if (!icon || icon === "") { |
||||
alert("Icon cannot be empty!"); |
||||
return true; |
||||
} |
||||
if (sequence < 0) { |
||||
alert("Order cannot be empty!"); |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
const saveMenuCompany = async () => { |
||||
let data = ''; |
||||
const err = validation(); |
||||
if (!err) { |
||||
if (typeDialog === "Edit") { |
||||
data = { |
||||
id, |
||||
sequence: parseInt(sequence), |
||||
icon, |
||||
} |
||||
|
||||
if (parentId && parentId > 0) { |
||||
data['parent_id'] = parentId |
||||
} |
||||
|
||||
const formData = data |
||||
const url = MENU_COMPANY_EDIT(data.id) |
||||
const result = await axios.put(url, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
closeDialog('success', 'Data menu berhasil diubah') |
||||
} else { |
||||
closeDialog('failed', 'Data menu gagal diubah') |
||||
} |
||||
} |
||||
setId(0) |
||||
setName('') |
||||
setUrl('') |
||||
setIcon('') |
||||
setParentId(null) |
||||
setSequence(0) |
||||
setAliasName('') |
||||
} else { |
||||
const selectedData = menuResource.filter(item => targetKeys.includes(item.key)); |
||||
const formDatas = selectedData.map(data => ({ |
||||
menu_id: data.key, |
||||
parent_id: data.parent_id, |
||||
company_id: companyID, |
||||
icon: data.icon, |
||||
alias_name: data.alias_name, |
||||
url: data.url, |
||||
sequence: data.sequence |
||||
})); |
||||
const result = await axios |
||||
.post(MENU_COMPANY_ADD, formDatas, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
if (result && result.status == 200) { |
||||
closeDialog('success', result.data.message) |
||||
} else { |
||||
closeDialog('failed', result.data.message) |
||||
} |
||||
} |
||||
} |
||||
|
||||
const handleCancel = () => { |
||||
closeDialog('cancel', 'none') |
||||
setId(0) |
||||
setName('') |
||||
setUrl('') |
||||
setIcon('') |
||||
setParentId(null) |
||||
setSequence(0) |
||||
setAliasName('') |
||||
} |
||||
|
||||
const handleChange = targetKeys => { |
||||
setTargetKeys(targetKeys) |
||||
}; |
||||
|
||||
const onChangeParent = (val) => { |
||||
setParentId(val) |
||||
} |
||||
|
||||
const setupSelectParent = () => { |
||||
return ( |
||||
<> |
||||
{menuResource.map((val, index) => { |
||||
return ( |
||||
<Option key={index} value={val.id}>{val.name}</Option> |
||||
) |
||||
})} |
||||
</> |
||||
) |
||||
} |
||||
|
||||
const renderForm = () => { |
||||
return ( |
||||
<Form> |
||||
<Row> |
||||
<Col md={12}> |
||||
<div style={{ justifyContent: 'center' }}> |
||||
<Transfer |
||||
showSearch |
||||
listStyle={{ |
||||
width: 250, |
||||
height: 300, |
||||
}} |
||||
titles={['Master Menu', `Menu ${companyName}`]} |
||||
targetKeys={targetKeys} |
||||
dataSource={menuResource} |
||||
onChange={handleChange} |
||||
render={item => item.name} |
||||
/> |
||||
</div> |
||||
</Col> |
||||
</Row> |
||||
|
||||
</Form> |
||||
) |
||||
} |
||||
const renderFormEdit = () => { |
||||
return ( |
||||
<Form> |
||||
<Row> |
||||
<Col md={12}> |
||||
<span style={{ color: "red" }}>*</span> Wajib diisi. |
||||
</Col> |
||||
</Row> |
||||
<Row> |
||||
<Col> |
||||
{/* <FormGroup> |
||||
<Label className="capitalize">{t('name')} Menu<span style={{ color: "red" }}>*</span></Label> |
||||
<Input type="hidden" value={name} onChange={(e) => setName(e.target.value)} placeholder={t('inputName')} /> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label className="capitalize">URL<span style={{ color: "red" }}>*</span></Label> |
||||
<Input type="hidden" value={url} onChange={(e) => setUrl(e.target.value)} placeholder={t('inputUrl')} /> |
||||
</FormGroup> */} |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('icon')}<span style={{ color: "red" }}>*</span> </Label> |
||||
<Input type="text" value={icon} onChange={(e) => setIcon(e.target.value)} placeholder={t('inputIcon')} /> |
||||
</FormGroup> |
||||
</Col> |
||||
<Col> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('order')}<span style={{ color: "red" }}>*</span></Label> |
||||
<Input type="text" min="0" value={sequence} onChange={(e) => setSequence(e.target.value.replace(/[^0-9]/g, ''))} placeholder={t('inputOrder')} /> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('parentMenu')}</Label> |
||||
<Select showSearch defaultValue={parentId} onChange={onChangeParent} placeholder={t('inputParentMenu')} style={{ width: '100%' }}> |
||||
{setupSelectParent()} |
||||
</Select> |
||||
</FormGroup> |
||||
{/* <FormGroup> |
||||
<Label className="capitalize">Alias Menu</Label> |
||||
<Input type="hidden" value={aliasName} onChange={(e) => setAliasName(e.target.value)} placeholder={t('inputAliasMenu')} /> |
||||
</FormGroup> */} |
||||
</Col> |
||||
</Row> |
||||
|
||||
</Form> |
||||
) |
||||
} |
||||
return ( |
||||
<> |
||||
<Modal ssize="md" scrollable={true} isOpen={openDialog} toggle={toggleDialog}> |
||||
<ModalHeader className="capitalize withBtn" toggle={closeDialog} style={{ width: "100%" }}> |
||||
Add Data Menu |
||||
</ModalHeader> |
||||
<ModalBody> |
||||
{typeDialog !== 'Edit' ? renderForm() : renderFormEdit()} |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={() => handleSave()}>{typeDialog}</Button>{''} |
||||
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>cancel</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
</> |
||||
) |
||||
|
||||
} |
||||
export default FormMenu; |
@ -0,0 +1,267 @@
|
||||
import React, { useState, useEffect } from 'react' |
||||
import { |
||||
Modal, ModalHeader, ModalBody, ModalFooter, |
||||
Button, Form, FormGroup, Label, Input, Col, Row |
||||
} from 'reactstrap'; |
||||
import { Select } from 'antd'; |
||||
import { USER_ADD, USER_EDIT } from '../../../const/ApiConst.js'; |
||||
import 'antd/dist/antd.css'; |
||||
import { useTranslation } from 'react-i18next'; |
||||
import axios from 'axios'; |
||||
const { Option } = Select |
||||
const token = window.localStorage.getItem('token'); |
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
const FormUser = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit, roleList, companyID }) => { |
||||
const { t } = useTranslation() |
||||
const [id, setId] = useState('') |
||||
const [resourceName, setResourceName] = useState('') |
||||
const [username, setUsername] = useState('') |
||||
const [password, setPassword] = useState('') |
||||
const [employeeType, setEmployeeType] = useState('') |
||||
const [phoneNo, setPhoneNo] = useState('') |
||||
const [email, setEmail] = useState('') |
||||
const [gender, setGender] = useState('') |
||||
const [ktpNumber, setKtpNumber] = useState('') |
||||
const [roleId, setRoleId] = useState('') |
||||
const [statusResource, setStatusResource] = useState('active') |
||||
|
||||
useEffect(() => { |
||||
if (typeDialog === "Edit") { |
||||
console.log(dataEdit); |
||||
setId(dataEdit.id) |
||||
setResourceName(dataEdit.name) |
||||
setUsername(dataEdit.username) |
||||
setPassword('') |
||||
setEmployeeType(dataEdit.employee_type) |
||||
setPhoneNo(dataEdit.phone_number) |
||||
setEmail(dataEdit.email) |
||||
setGender(dataEdit.gender) |
||||
setKtpNumber(dataEdit.ktp_number ? dataEdit.ktp_number : '') |
||||
setRoleId(dataEdit.role_id) |
||||
} else { |
||||
setId(0) |
||||
setResourceName('') |
||||
setUsername('') |
||||
setPassword('') |
||||
setEmployeeType('') |
||||
setPhoneNo('') |
||||
setEmail('') |
||||
setGender('') |
||||
setRoleId('') |
||||
} |
||||
}, [dataEdit, openDialog]) |
||||
|
||||
|
||||
const handleSave = async () => { |
||||
let data = ''; |
||||
if (typeDialog === "Save") { |
||||
data = { |
||||
name: resourceName, |
||||
employee_type: employeeType, |
||||
phone_number: phoneNo, |
||||
email, |
||||
gender, |
||||
ktp_number: ktpNumber, |
||||
role_id: roleId, |
||||
status_resource: statusResource, |
||||
company_id: companyID, |
||||
username, |
||||
password, |
||||
} |
||||
const formData = data |
||||
const result = await axios.post(USER_ADD, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
closeDialog('success', `Data resource berhasil ditambah`) |
||||
} else { |
||||
closeDialog('failed', result.data.message) |
||||
} |
||||
} else { |
||||
|
||||
data = { |
||||
id, |
||||
name: resourceName, |
||||
username, |
||||
employee_type: employeeType, |
||||
phone_number: phoneNo, |
||||
email, |
||||
gender, |
||||
ktp_number: ktpNumber, |
||||
role_id: roleId, |
||||
status_resource: statusResource, |
||||
company_id: companyID, |
||||
username, |
||||
password, |
||||
} |
||||
if (password == '') { |
||||
data.password = dataEdit.password; |
||||
} |
||||
let urlEdit = USER_EDIT(data.id) |
||||
const formData = data |
||||
|
||||
const result = await axios.put(urlEdit, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
closeDialog('success', `Data resource berhasil diedit`) |
||||
} else { |
||||
closeDialog('failed', result.data.message) |
||||
} |
||||
|
||||
} |
||||
} |
||||
|
||||
const handleCancel = () => { |
||||
closeDialog('cancel', 'none') |
||||
} |
||||
|
||||
const isValidEmail = (email) => { |
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; |
||||
return emailRegex.test(email); |
||||
}; |
||||
|
||||
const setupSelectRole = () => { |
||||
return ( |
||||
<> |
||||
{roleList.map((val, index) => { |
||||
return ( |
||||
<Option key={index} value={val.id}>{val.name}</Option> |
||||
) |
||||
})} |
||||
</> |
||||
) |
||||
} |
||||
|
||||
|
||||
const renderFormSetAdmin = () => { |
||||
return ( |
||||
<Form> |
||||
<Row> |
||||
<Col md={12}> |
||||
<span style={{ color: "red" }}>*</span>required. |
||||
</Col> |
||||
</Row> |
||||
<Row> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('nik')} <span style={{ color: "red" }}>*</span></Label> |
||||
<Input type="text" value={ktpNumber} onChange={(e) => setKtpNumber(e.target.value.replace(/[^0-9]/g, ''))} placeholder={t('inputNik')} maxLength="16" /> |
||||
</FormGroup> |
||||
</Col> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('nameHR')}<span style={{ color: "red" }}>*</span></Label> |
||||
<Input type="text" value={resourceName} onChange={(e) => setResourceName(e.target.value)} placeholder={t('inputName')} /> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
<Row> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('employeeType')} <span style={{ color: "red" }}>*</span></Label> |
||||
<Select showSearch value={employeeType} defaultValue={employeeType} onChange={(val) => setEmployeeType(val)} placeholder="Select Employee Type" style={{ width: '100%' }}> |
||||
<Option value={'employee'}>Employee</Option> |
||||
<Option value={'subcon'}>Subcon</Option> |
||||
<Option value={'freelance'}>Freelance</Option> |
||||
</Select> |
||||
</FormGroup> |
||||
|
||||
</Col> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">Phone No.</Label> |
||||
<Input type="text" value={phoneNo} onChange={(e) => setPhoneNo(e.target.value.replace(/[^0-9]/g, ''))} placeholder={t('inputNoPhone')} maxLength="15" /> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
<Row> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">Email</Label> |
||||
<Input type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder={t('inputEmail')} |
||||
onBlur={(e) => { |
||||
if (!isValidEmail(e.target.value)) { |
||||
alert("Masukkan email yang valid."); |
||||
} |
||||
}} |
||||
/> |
||||
</FormGroup> |
||||
</Col> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('gender')}</Label> |
||||
<Select showSearch value={gender} defaultValue={gender} onChange={(val) => setGender(val)} placeholder={t('selectGender')} style={{ width: '100%' }}> |
||||
<Option value="Male">Male</Option> |
||||
<Option value="Female">Female</Option> |
||||
{/* <Option value="Other">Other</Option> */} |
||||
</Select> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
<Row> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('roles')} <span style={{ color: "red" }}>*</span></Label> |
||||
<Select showSearch defaultValue={roleId} onChange={(val) => setRoleId(val)} placeholder={t('selectRole')} style={{ width: '100%' }}> |
||||
{setupSelectRole()} |
||||
</Select> |
||||
</FormGroup> |
||||
</Col> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">Status</Label> |
||||
<Select style={{ width: "100%" }} defaultValue={statusResource} onChange={(e) => setStatusResource(e)} > |
||||
<Option value={'active'}>Active</Option> |
||||
<Option value={'inactive'}>Inactive</Option> |
||||
</Select> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
<Row> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">Username</Label> |
||||
<Input type="text" value={username} onChange={(e) => setUsername(e.target.value)} placeholder={`Username...`} /> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
<Row> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">Password</Label> |
||||
<Input type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder={`Password...`} /> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
</Form> |
||||
) |
||||
} |
||||
|
||||
return ( |
||||
<> |
||||
<Modal size="xl" fullscreen="xl" scrollable={true} isOpen={openDialog} toggle={toggleDialog}> |
||||
<ModalHeader className="capitalize withBtn" toggle={closeDialog} style={{ width: "100%" }}> |
||||
{typeDialog === "Save" ? `Add` : typeDialog === "Set" ? "Add " : "Edit"} User |
||||
</ModalHeader> |
||||
<ModalBody> |
||||
{renderFormSetAdmin()} |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={() => handleSave()}>{typeDialog}</Button>{''} |
||||
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>cancel</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
</> |
||||
) |
||||
|
||||
} |
||||
export default FormUser; |
@ -0,0 +1,361 @@
|
||||
import * as XLSX from 'xlsx'; |
||||
import React, { useState, useEffect, useMemo } from 'react'; |
||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
||||
import axios from "../../../const/interceptorApi" |
||||
import { Card, CardBody, CardHeader, Col, Row, Input } from 'reactstrap'; |
||||
import DialogForm from './DialogForm' |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import { Pagination, Table, Button, Tooltip } from 'antd'; |
||||
import { |
||||
COMPANY_MANAGEMENT_SEARCH, USER_ADD, USER_SEARCH, USER_EDIT, USER_DELETE, DIVISI_SEARCH, USER_SHIFT_ADD, USER_SYNC |
||||
} from '../../../const/ApiConst'; |
||||
import { useTranslation } from 'react-i18next'; |
||||
const token = window.localStorage.getItem('token'); |
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
|
||||
const MasterCompany = ({ params }) => { |
||||
const token = localStorage.getItem("token") |
||||
const company_id = localStorage.getItem("company_id") |
||||
const HEADER = { |
||||
headers: { |
||||
"Content-Type": "application/json", |
||||
"Authorization": `Bearer ${token}` |
||||
} |
||||
} |
||||
const [alertDelete, setAlertDelete] = useState(false) |
||||
const [clickOpenModal, setClickOpenModal] = useState(false) |
||||
const [clickOpenModalShift, setClickOpenModalShift] = useState(false) |
||||
const [currentPage, setCurrentPage] = useState(1) |
||||
const [dataEdit, setDataEdit] = useState([]) |
||||
const [dataExport, setDataExport] = useState([]) |
||||
const [dataTable, setDatatable] = useState([]) |
||||
const [divisiList, setDivisiList] = useState([]) |
||||
const [idDelete, setIdDelete] = useState(0) |
||||
const [openDialog, setOpenDialog] = useState(false) |
||||
const [openDialogShift, setOpenDialogShift] = useState(false) |
||||
const [rowsPerPage, setRowsPerPage] = useState(10) |
||||
const [search, setSearch] = useState('') |
||||
const [totalPage, setTotalPage] = useState(0) |
||||
const [typeDialog, setTypeDialog] = useState('Save') |
||||
const [typeDialogShift, setTypeDialogShift] = useState('Save') |
||||
const [companyID, setCompanyID] = useState('') |
||||
const [companyName, setCompanyName] = useState('') |
||||
const pageName = params.name; |
||||
const { t } = useTranslation(); |
||||
useEffect(() => { |
||||
getDivisiList() |
||||
}, []) |
||||
|
||||
useEffect(() => { |
||||
getDataUser() |
||||
}, [search, rowsPerPage, currentPage]) |
||||
|
||||
|
||||
|
||||
const onShowSizeChange = (current, pageSize) => { |
||||
setRowsPerPage(pageSize) |
||||
} |
||||
|
||||
const onPagination = (current, pageSize) => { |
||||
setCurrentPage(current) |
||||
} |
||||
|
||||
const getDivisiList = async () => { |
||||
const formData = { |
||||
"paging": { "start": 0, "length": -1 }, |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(DIVISI_SEARCH, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
setDivisiList(result.data.data); |
||||
} else { |
||||
NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
const getDataUser = async () => { |
||||
|
||||
let start = 0; |
||||
|
||||
if (currentPage !== 1 && currentPage > 1) { |
||||
start = (currentPage * rowsPerPage) - rowsPerPage |
||||
} |
||||
|
||||
const payload = { |
||||
"paging": { |
||||
"start": start, |
||||
"length": rowsPerPage |
||||
}, |
||||
"columns": [], |
||||
"group_column": { |
||||
"operator": "AND", |
||||
"group_operator": "OR", |
||||
"where": [ |
||||
{ |
||||
"name": "name", |
||||
"logic_operator": "~*", |
||||
"value": search |
||||
}, |
||||
{ |
||||
"name": "phone_number", |
||||
"logic_operator": "~*", |
||||
"value": search |
||||
}, |
||||
{ |
||||
"name": "email", |
||||
"logic_operator": "~*", |
||||
"value": search |
||||
}, |
||||
{ |
||||
"name": "status_resource", |
||||
"logic_operator": "~*", |
||||
"value": search |
||||
}, |
||||
] |
||||
}, |
||||
"joins": [ |
||||
|
||||
], |
||||
"orders": { |
||||
"columns": [ |
||||
"id" |
||||
], |
||||
"ascending": true |
||||
} |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(COMPANY_MANAGEMENT_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
setDatatable(result.data.data); |
||||
setTotalPage(result.data.totalRecord); |
||||
} else { |
||||
NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
const handleSearch = e => { |
||||
const value = e.target.value |
||||
setSearch(value); |
||||
setCurrentPage(1) |
||||
}; |
||||
|
||||
const handleOpenDialog = async (type) => { |
||||
await setTypeDialog(type) |
||||
setOpenDialog(true) |
||||
|
||||
} |
||||
|
||||
|
||||
|
||||
const handleEdit = (data) => { |
||||
setDataEdit(data) |
||||
handleOpenDialog('Edit'); |
||||
} |
||||
|
||||
const handleSetWorker = async (data) => { |
||||
setCompanyID(data.id) |
||||
setCompanyName(data.company_name) |
||||
await setDataEdit(data) |
||||
handleOpenDialog('Set'); |
||||
} |
||||
|
||||
const handleSetMenu = async (data) => { |
||||
setCompanyID(data.id) |
||||
setCompanyName(data.company_name) |
||||
await setDataEdit(data) |
||||
handleOpenDialog('Set-Menu'); |
||||
} |
||||
|
||||
|
||||
const handleDelete = async (id) => { |
||||
await setAlertDelete(true) |
||||
await setIdDelete(id) |
||||
} |
||||
|
||||
const handleCloseDialog = (type, data) => { |
||||
if (type === "save") { |
||||
saveUser(data); |
||||
} else if (type === "edit") { |
||||
editUser(data); |
||||
} |
||||
setDataEdit([]) |
||||
setOpenDialog(false) |
||||
} |
||||
|
||||
|
||||
const saveUser = async (data) => { |
||||
const formData = data |
||||
const result = await axios.post(USER_ADD, formData, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataUser(); |
||||
NotificationManager.success(`Data resource berhasil ditambah`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`${result.data.message}`, 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
const editUser = async (data) => { |
||||
|
||||
let urlEdit = USER_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) { |
||||
getDataUser(); |
||||
NotificationManager.success(`Data resource berhasil diedit`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`${result.data.message}`, `Failed!!`); |
||||
} |
||||
} |
||||
|
||||
const toggleAddDialog = () => { |
||||
setOpenDialog(!openDialog) |
||||
} |
||||
|
||||
|
||||
|
||||
const onConfirmDelete = async () => { |
||||
let url = USER_DELETE(idDelete); |
||||
|
||||
const result = await axios.delete(url, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataUser() |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.success(`Data user berhasil dihapus!`, 'Success!!'); |
||||
} else { |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.error(`Data user gagal dihapus!}`, 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
const cancelDelete = () => { |
||||
setAlertDelete(false) |
||||
setIdDelete(0) |
||||
} |
||||
|
||||
const RenderTable = useMemo(() => { |
||||
const columns = [ |
||||
{ |
||||
title: t('action'), |
||||
dataIndex: '', |
||||
key: 'x', |
||||
render: (text, record) => <> |
||||
<Tooltip title={t('edit')}> |
||||
<Button size="small" type="link" style={{ color: 'green' }} onClick={() => handleEdit(text)}><i className="fa fa-edit"></i></Button> |
||||
</Tooltip> |
||||
<Tooltip title={t('delete')}> |
||||
<Button size="small" type="link" style={{ color: 'red' }} onClick={() => handleDelete(text.id)}><i className="fa fa-trash"></i></Button> |
||||
</Tooltip> |
||||
<Tooltip title="Set User"> |
||||
<Button size="small" type="link" style={{ color: 'primary' }} onClick={() => handleSetWorker(text)}><i className="fa fa-users"></i></Button> |
||||
</Tooltip> |
||||
<Tooltip title="Set Menu"> |
||||
<Button size="small" type="link" style={{ color: 'orange' }} onClick={() => handleSetMenu(text)}><i className="fa fa-bars"></i></Button> |
||||
</Tooltip> |
||||
</>, |
||||
}, |
||||
|
||||
{ title: "Number Registration", dataIndex: 'registration_no', key: 'registration_no' }, |
||||
{ title: "Name", dataIndex: 'company_name', key: 'company_name' }, |
||||
{ title: 'Phone No.', dataIndex: 'phone_no', key: 'phone_no' }, |
||||
{ title: 'Email', dataIndex: 'email', key: 'email' }, |
||||
{ title: 'Status', dataIndex: 'is_active', key: 'is_active', render: (text, record) => <>{text && text !== false ? "Active" : 'Inactive'}</> } |
||||
]; |
||||
return ( |
||||
<Table |
||||
rowKey="id" |
||||
size="small" |
||||
columns={columns} |
||||
dataSource={dataTable} |
||||
pagination={false} |
||||
/> |
||||
) |
||||
}, [dataTable]) |
||||
|
||||
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} |
||||
divisiList={divisiList} |
||||
companyID={companyID} |
||||
companyNameProp={companyName} |
||||
/> |
||||
|
||||
<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='Search Company' /> |
||||
</Col> |
||||
<Col> |
||||
<Tooltip title='Add Company'> |
||||
<Button style={{ background: "#4caf50", color: "#fff" }} onClick={() => handleOpenDialog('Save')}><i className="fa fa-plus"></i></Button> |
||||
</Tooltip> |
||||
</Col> |
||||
</Row> |
||||
</CardHeader> |
||||
<CardBody> |
||||
{RenderTable} |
||||
<Pagination |
||||
style={{ marginTop: "25px" }} |
||||
showSizeChanger |
||||
onShowSizeChange={onShowSizeChange} |
||||
onChange={onPagination} |
||||
pageSizeOptions={["10", "25", "50"]} |
||||
total={totalPage} |
||||
pageSize={rowsPerPage} |
||||
current={currentPage} |
||||
/> |
||||
</CardBody> |
||||
</Card> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
export default MasterCompany; |
@ -0,0 +1,345 @@
|
||||
import React, { Component } from 'react'; |
||||
import { Link } from 'react-router-dom'; |
||||
import "slick-carousel/slick/slick.css"; |
||||
import "slick-carousel/slick/slick-theme.css"; |
||||
import Slider from "react-slick"; |
||||
import { Spin } from 'antd'; |
||||
import { Checkbox } from 'antd'; |
||||
import { LoadingOutlined, EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons'; |
||||
import { |
||||
Button, |
||||
Card, |
||||
CardBody, |
||||
CardGroup, |
||||
Col, |
||||
Container, |
||||
Form, |
||||
Input, |
||||
InputGroup, |
||||
InputGroupAddon, |
||||
InputGroupText, |
||||
Row, |
||||
UncontrolledAlert, |
||||
Alert, |
||||
Carousel, |
||||
CarouselIndicators, |
||||
CarouselCaption, |
||||
CarouselItem, |
||||
CarouselControl |
||||
} from 'reactstrap'; |
||||
import { USER_LOGIN, USER_LOGIN_V2, CALERTUSER_SEARCH, MENU_MANAGEMENT, APP_MODE } from '../../../const/ApiConst.js'; |
||||
import { appConfig, reloadConstants } from '../../../const/MapConst.js'; |
||||
import { APP_NAME } from '../../../const/AppConst.js' |
||||
import moment from "moment" |
||||
import axios from 'axios'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import logo_login_adw from '../../../assets/img/logo_adyawinsa.jpg' |
||||
import logo_login_kit from '../../../assets/img/logo_kit.png' |
||||
import logo_login_nawakara from '../../../assets/img/logo_nawakara.png' |
||||
import logo_login_si from '../../../assets/img/logo-surveyor-indonesia.png' |
||||
import logo_ospro from '../../../assets/img/OSPRO.png' |
||||
|
||||
const antIcon = <LoadingOutlined style={{ fontSize: 24 }} spin />; |
||||
|
||||
const settings = { |
||||
dots: true, |
||||
infinite: true, |
||||
speed: 500, |
||||
arrows: false, |
||||
autoplay: true, |
||||
slidesToShow: 1, |
||||
slidesToScroll: 1 |
||||
}; |
||||
|
||||
class Login extends Component { |
||||
constructor(props) { |
||||
super(props); |
||||
this.state = { |
||||
name: '', |
||||
password: '', |
||||
remember: '', |
||||
alertVisible: false, |
||||
alertMessage: '', |
||||
alertColor: 'success', |
||||
validate: { |
||||
emailState: '', |
||||
}, |
||||
loader: false, |
||||
type: 'password' |
||||
} |
||||
this.handleChange = this.handleChange.bind(this); |
||||
this.showHide = this.showHide.bind(this); |
||||
} |
||||
showHide(e) { |
||||
e.preventDefault(); |
||||
e.stopPropagation(); |
||||
this.setState({ |
||||
type: this.state.type === 'input' ? 'password' : 'input' |
||||
}) |
||||
} |
||||
validateEmail(e) { |
||||
const emailRex = /^(([^<>()[\]\\.,;:\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,}))$/; |
||||
const { validate } = this.state |
||||
if (emailRex.test(e.target.value)) { |
||||
validate.emailState = 'has-success' |
||||
} else { |
||||
validate.emailState = 'has-danger' |
||||
} |
||||
this.setState({ validate }) |
||||
} |
||||
|
||||
handleChange = async (event) => { |
||||
const { target } = event; |
||||
const value = target.type === 'checkbox' ? target.checked : target.value; |
||||
const { name } = target; |
||||
await this.setState({ |
||||
[name]: value, |
||||
}); |
||||
} |
||||
|
||||
getDataMenu = async (token, role_id) => { |
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
|
||||
let url = MENU_MANAGEMENT(role_id) |
||||
const result = await axios |
||||
.get(url, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
let resData = result.data.data |
||||
window.localStorage.setItem('menu_login', JSON.stringify(resData)); |
||||
this.setState({ loader: false }) |
||||
// custom redirect home after login |
||||
if (role_id == 28) { |
||||
this.props.history.push("/dashboard-customer/58/63"); |
||||
} |
||||
else { |
||||
this.props.history.push("/dashboard"); |
||||
} |
||||
} else { |
||||
NotificationManager.error('Login Failed', 'Failed'); |
||||
this.setState({ loader: false }) |
||||
} |
||||
} |
||||
|
||||
submitForm = (event) => { |
||||
event.preventDefault(); |
||||
this.submitFormLogin(); |
||||
} |
||||
|
||||
submitFormLogin = async () => { |
||||
this.setState({ loader: true }) |
||||
const { name, password, remember } = this.state |
||||
|
||||
if (name === '') { |
||||
NotificationManager.error('Please fill username', 'Login Failed!'); |
||||
this.setState({ loader: false }) |
||||
return false; |
||||
} |
||||
|
||||
if (password === '') { |
||||
NotificationManager.error('Please fill password', 'Login Failed!'); |
||||
this.setState({ loader: false }) |
||||
return false; |
||||
} |
||||
|
||||
let formData = { |
||||
username: name, |
||||
password, |
||||
remember, |
||||
} |
||||
|
||||
const doLogin = await axios.post(USER_LOGIN_V2, formData) |
||||
.then(response => response) |
||||
.catch(error => { |
||||
this.setState({ loader: false }); |
||||
}); |
||||
|
||||
if (doLogin && doLogin.data && doLogin.data.code === 200) { |
||||
const { access_token, data_user } = doLogin.data.data |
||||
this.getDataMenu(access_token, data_user.role_id) |
||||
window.localStorage.setItem('isLogin', true); |
||||
window.localStorage.setItem('token', access_token); |
||||
window.localStorage.setItem('user_id', data_user.id); |
||||
window.localStorage.setItem('user_name', data_user.name); |
||||
window.localStorage.setItem('role_id', data_user.role_id); |
||||
} else { |
||||
console.log("kode : ", doLogin.data.code); |
||||
// NotificationManager.error('Cek username atau password anda!', 'Gagal Login!'); |
||||
NotificationManager.error(doLogin.data.message, 'Login Failed!'); |
||||
this.setState({ loader: false }); |
||||
} |
||||
|
||||
} |
||||
|
||||
getConfigAlert = async (token, user_id) => { |
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
|
||||
const payload = { |
||||
"paging": { "start": 0, "length": -1 }, |
||||
"columns": [ |
||||
{ "name": "user_id", "logic_operator": "=", "value": `${user_id}`, "operator": "AND" } |
||||
], |
||||
"joins": [], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(CALERTUSER_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
let resData = result.data.data |
||||
let configAlert = [] |
||||
resData.map((val, index) => { |
||||
configAlert.push(val.config_alert_id); |
||||
}); |
||||
window.localStorage.setItem('userConfigAlert', configAlert.join()); |
||||
} |
||||
} |
||||
|
||||
onShowAlert = (alertColor, alertMessage) => { |
||||
this.setState({ alertVisible: true, alertColor: alertColor, alertMessage: alertMessage }, () => { |
||||
window.setTimeout(() => { |
||||
this.setState({ alertVisible: false }) |
||||
}, 3000) |
||||
}); |
||||
} |
||||
|
||||
getLoginLogo = () => { |
||||
return <div style={{ textAlign: 'center' }}><img style={{ width: '100%' }} src={logo_ospro} /></div> |
||||
} |
||||
|
||||
getLoginSlider = () => { |
||||
return <Slider {...settings} > |
||||
<div> |
||||
<img src={require('../../../assets/img/login/slide1.jpg')} className="img-avatar" /> |
||||
</div> |
||||
<div> |
||||
<img src={require('../../../assets/img/login/slide2.jpg')} className="img-avatar" /> |
||||
</div> |
||||
<div> |
||||
<img src={require('../../../assets/img/login/slide3.jpg')} className="img-avatar" /> |
||||
</div> |
||||
<div> |
||||
<img src={require('../../../assets/img/login/slide4.jpg')} className="img-avatar" /> |
||||
</div> |
||||
</Slider> |
||||
} |
||||
|
||||
onChecked = (e) => { |
||||
this.setState({ remember: e.target.checked }) |
||||
}; |
||||
|
||||
render() { |
||||
const { name, password, remember } = this.state; |
||||
const u_group = window.localStorage.getItem('u_group') |
||||
if (u_group !== null) { |
||||
this.props.history.push("/dashboard"); |
||||
} |
||||
return ( |
||||
<div className="app flex-row align-items-center"> |
||||
<Container> |
||||
<NotificationContainer /> |
||||
|
||||
<Alert color={this.state.alertColor} isOpen={this.state.alertVisible} > |
||||
{this.state.alertMessage} |
||||
</Alert> |
||||
<Row className="justify-content-center"> |
||||
<Col md="7"> |
||||
{this.getLoginSlider()} |
||||
</Col> |
||||
<Col md="5"> |
||||
<div style={{ |
||||
boxShadow: '1px 1px 11px 1px rgba(221,211,211,0.75)' |
||||
}}> |
||||
<CardGroup> |
||||
<Card className="p-4"> |
||||
<CardBody> |
||||
<Form onSubmit={this.submitForm}> |
||||
{this.getLoginLogo()} <p className="text-muted">Sign In to your account</p> <InputGroup className="mb-3"> |
||||
<InputGroupAddon addonType="prepend"> |
||||
<InputGroupText> |
||||
<i className="icon-user"></i> |
||||
</InputGroupText> |
||||
</InputGroupAddon> |
||||
<Input |
||||
type="text" |
||||
name="name" |
||||
id="exampleName" |
||||
placeholder="Username" |
||||
value={name} |
||||
onChange={(e) => { |
||||
this.setState({ name: e.target.value }) |
||||
}} |
||||
/> |
||||
</InputGroup> |
||||
<InputGroup className="mb-4"> |
||||
<InputGroupAddon addonType="prepend"> |
||||
<InputGroupText> |
||||
<i className="icon-lock"></i> |
||||
</InputGroupText> |
||||
</InputGroupAddon> |
||||
<Input |
||||
type={this.state.type} |
||||
name="password" |
||||
id="examplePassword" |
||||
placeholder="********" |
||||
value={password} |
||||
onChange={(e) => this.setState({ password: e.target.value })} |
||||
/> |
||||
<InputGroupAddon addonType="prepend"> |
||||
<InputGroupText |
||||
onClick={this.showHide} |
||||
> |
||||
{this.state.type === 'input' ? <EyeOutlined /> : <EyeInvisibleOutlined />} |
||||
|
||||
</InputGroupText> |
||||
</InputGroupAddon> |
||||
<span className="password__show" ></span> |
||||
</InputGroup> |
||||
<Row> |
||||
<Col xs="8"> |
||||
<Checkbox checked={this.state.remember} onChange={this.onChecked}>Remember me (7 days)</Checkbox> |
||||
</Col> |
||||
<Col xs="4"> |
||||
{this.state.loader ? ( |
||||
<Spin indicator={antIcon} /> |
||||
) : ( |
||||
<Button onClick={() => this.submitFormLogin()} color="primary" className="px-4" >Login</Button> |
||||
)} |
||||
</Col> |
||||
</Row> |
||||
<Row> |
||||
<Col className="text-right mt-5"> |
||||
<Button color="link" className="px-0">Forgot password?</Button> |
||||
</Col> |
||||
</Row> |
||||
</Form> |
||||
</CardBody> |
||||
</Card> |
||||
</CardGroup> |
||||
</div> |
||||
</Col> |
||||
</Row> |
||||
</Container> |
||||
</div> |
||||
); |
||||
} |
||||
} |
||||
|
||||
export default Login; |
Loading…
Reference in new issue