Browse Source

Merge pull request 'profile slacing' (#61) from dev-wahyun into staging

Reviewed-on: ibnu/generic-ospro-frontend#61
pull/1/head
farhantock 7 months ago
parent
commit
6c17815af7
  1. 28
      src/const/ApiConst.js
  2. 592
      src/containers/DefaultLayout/DefaultHeader.js
  3. 2
      src/routes.js
  4. 31
      src/views/Master/MasterCompany/index.js
  5. 8
      src/views/SimproV2/CreatedProyek/DialogDocument.js
  6. 12
      src/views/SimproV2/CreatedProyek/FormDocument.js
  7. 53
      src/views/SimproV2/Settings/Desktop.js
  8. 23
      src/views/SimproV2/Settings/Desktop.module.css
  9. 184
      src/views/SimproV2/Settings/DialogForm.js
  10. 69
      src/views/SimproV2/Settings/components/MyProfile/Head.module.css
  11. 436
      src/views/SimproV2/Settings/components/MyProfile/Index.js
  12. 563
      src/views/SimproV2/Settings/components/MyProfile/Index.module.css
  13. 65
      src/views/SimproV2/Settings/components/Plan/Column.js
  14. 114
      src/views/SimproV2/Settings/components/Plan/Column.module.css
  15. 69
      src/views/SimproV2/Settings/components/Plan/Container.js
  16. 229
      src/views/SimproV2/Settings/components/Plan/Container.module.css
  17. 226
      src/views/SimproV2/Settings/components/Plan/Container1.js
  18. 356
      src/views/SimproV2/Settings/components/Plan/Container1.module.css
  19. 5
      src/views/SimproV2/Settings/index.js

28
src/const/ApiConst.js

@ -125,7 +125,9 @@ export let BASE_SIMPRO_LUMEN_FILE = `${BASE_OSPRO}/assets/file/project`;
export let BASE_SIMPRO_LUMEN_FILE_COMPANY = (file, company_name)=>{
return `${BASE_OSPRO}/assets/${company_name}/file/project/${file}`;
}
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"
@ -300,6 +302,19 @@ export const REFFERAL_EDIT = (id) => {
return `${BASE_SIMPRO_LUMEN}/refferal-code/update/${id}`;
};
export const TRANSACTION_ADD = `${BASE_SIMPRO_LUMEN}/product-transaction/add`;
export const TRANSACTION_SEARCH = `${BASE_SIMPRO_LUMEN}/product-transaction/search`;
export const TRANSACTION_GET_ID = (id) => {
return `${BASE_SIMPRO_LUMEN}/product-transaction/edit/${id}`;
};
export const TRANSACTION_EDIT = (id) => {
return `${BASE_SIMPRO_LUMEN}/product-transaction/update/${id}`;
};
export const STORAGE_LIMIT_INFORMATION = (company_name) => {
return `${BASE_SIMPRO_LUMEN}/information-storage/${company_name}`;
};
export const ABSENSI_ADD = `${BASE_SIMPRO_LUMEN}/permit/add`;
export const ABSENSI_SEARCH = `${BASE_SIMPRO_LUMEN}/permit/search`;
export const ABSENSI_EDIT = (id) => {
@ -733,12 +748,6 @@ export const ASSIGN_HR_PROJECT_DELETE = (id, company_id) => {
};
export const ASSIGN_HR_PROJECT_LIST = `${BASE_SIMPRO_LUMEN}/user-to-proyek/list`;
export const IMAGE_GET_BY_ID = (id, category) => {
return `${BASE_SIMPRO_LUMEN}/image/${id}/${category}`;
};
export const IMAGE_SEARCH = `${BASE_SIMPRO_LUMEN}/image/search`;
export const OSPRO_BASE_IMAGE = `${BASE_OSPRO}/api/assets/image`;
export const DASHBOARD_COST_PLANNING_ACTUAL = `${BASE_SIMPRO_LUMEN}/dashboard/cost-planning-actual`;
export const DASHBOARD_PERSENTASE_PROGRESS_PROYEK = `${BASE_SIMPRO_LUMEN}/dashboard/percentage-planning-actual`;
export const DASHBOARD_REPORT_POINTS = `${BASE_SIMPRO_LUMEN}/report-activity/search-point`;
@ -798,6 +807,11 @@ export const HIERARCHY_FTTH_COUNT_TREE = (id) => {
export const WAYPOINT_SEARCH = `${BASE_SIMPRO_LUMEN}/waypoint/search`;
export const IMAGE_GET_BY_ID = (id, category) => {
return `${BASE_SIMPRO_LUMEN}/image/${id}/${category}`;
};
export const IMAGE_SEARCH = `${BASE_SIMPRO_LUMEN}/image/search`;
export const OSPRO_BASE_IMAGE = `${BASE_OSPRO}/api/assets/image`;
export const IMAGE_UPLOAD = `${BASE_SIMPRO_LUMEN}/image/upload`;
export const IMAGE_MULTIPLE_UPLOAD = `${BASE_SIMPRO_LUMEN}/image/multiple-upload`;
export const IMAGE_MULTIPLE_DELETE = (id, category, company_id) => {

592
src/containers/DefaultLayout/DefaultHeader.js

@ -1,296 +1,296 @@
import React, { Component } from 'react';
import { NavLink } from 'react-router-dom';
import { Badge, Nav, NavItem } from 'reactstrap';
import PropTypes from 'prop-types';
import { Menu, Dropdown } from 'antd'
import { ALERTUSER_SEARCH, ALERT_SEARCH, ALERTUSER_STATUSVIEW, ALERT_STATUSVIEW, APP_MODE, BASE_SIMPRO_LUMEN_IMAGE } from '../../const/ApiConst';
import { AppAsideToggler, AppNavbarBrand, AppSidebarToggler } from '@coreui/react';
import logo_ospro from '../../assets/img/OSPRO.png'
import axios from 'axios';
import './Default.css'
const propTypes = {
children: PropTypes.node,
};
const defaultProps = {};
class DefaultHeader extends Component {
constructor(props) {
super(props);
this.state = {
fullname: localStorage.getItem('fullname'),
u_group: localStorage.getItem('u_group'),
dataAlert: [],
totalAlert: 0,
listReadNotif: []
}
this.callAlert = "";
}
componentDidMount() {
this.getHeaderMenu();
const token = window.localStorage.getItem('token');
const role = window.localStorage.getItem('role_name');
if (role !== 'Super Admin') {
this.setState({
configApp: JSON.parse(window.localStorage.getItem('configApp')),
});
}
this.setState({
config: {
headers: {
Authorization: `Bearer ${token}`,
'Content-type': `application/json`,
},
},
});
}
getLogoHeaderContent = () => {
const { configApp } = this.state;
const logoHeaderContent = configApp && configApp.logo_header ? configApp.logo_header.content : null;
return logoHeaderContent
? `${BASE_SIMPRO_LUMEN_IMAGE}/${logoHeaderContent}`
: logo_ospro;
};
componentDidUpdate(prevProps, prevState) {
if (this.state.listReadNotif !== prevState.listReadNotif) {
if (this.state.listReadNotif.length > 0) {
this.markAsRead();
}
}
}
componentWillUnmount() {
clearInterval(this.callAlert);
}
getDataAlert = async () => {
let url = '';
let payload = '';
if (parseInt(localStorage.getItem('role_id')) === 1) {
url = ALERT_SEARCH;
payload = {
"paging": { "start": 0, "length": -1 },
"columns": [
{ "name": "status_view", "logic_operator": "=", "value": "false", "operator": "AND" },
],
"joins": [
{ "name": "config_alert", "column_join": "config_alert_id", "column_results": ["nama", "keterangan"] },
{ "name": "laporan_planning", "column_join": "laporan_planning_id", "column_results": ["deskripsi", "status", "jumlah_pekerjaan"] },
{ "name": "m_satuan", "column_join": "satuan_id", "column_results": ["name", "description"] }
],
"orders": { "columns": ["created_at"], "ascending": false }
}
} else {
url = ALERTUSER_SEARCH;
payload = {
"paging": { "start": 0, "length": -1 },
"columns": [
{ "name": "status_view", "logic_operator": "=", "value": "false", "operator": "AND" },
{ "name": "user_id", "logic_operator": "=", "value": localStorage.getItem('user_id'), "operator": "AND" },
],
"joins": [
{ "name": "alert", "column_join": "alert_id", "column_results": ["nama", "keterangan"] },
{ "name": "config_alert", "column_join": "config_alert_id", "column_results": ["nama", "keterangan"] },
{ "name": "laporan_planning", "column_join": "laporan_planning_id", "column_results": ["deskripsi", "status", "jumlah_pekerjaan"] },
{ "name": "m_satuan", "column_join": "satuan_id", "column_results": ["name", "description"] },
{ "name": "m_users", "column_join": "user_id", "column_results": ["name", "username", "email", "phone_number", "gender"] }
],
"orders": { "columns": ["created_at"], "ascending": false }
}
}
if (localStorage.getItem('userConfigAlert')) {
if (parseInt(localStorage.getItem('role_id')) === 1) {
payload['columns'].push({ "name": "config_alert_id", "logic_operator": "IN", "value": localStorage.getItem('userConfigAlert'), "operator": "AND" })
} else {
payload['columns'].push({ "name": "config_alert_id", "logic_operator": "IN", "value": localStorage.getItem('userConfigAlert'), "operator": "AND", "table_name": "alert" })
}
} else {
if (parseInt(localStorage.getItem('role_id')) === 1) {
payload['columns'].push({ "name": "config_alert_id", "logic_operator": "IN", "value": "0", "operator": "AND" })
} else {
payload['columns'].push({ "name": "config_alert_id", "logic_operator": "IN", "value": "0", "operator": "AND", "table_name": "alert" })
}
}
const result = await axios
.post(url, payload, this.state.config)
.then(res => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
this.setState({ dataAlert: result.data.data, totalAlert: result.data.totalRecord });
}
}
dropDownMenu = () => {
const { dataAlert, totalAlert } = this.state
let dataAlertLength = dataAlert.length
let currentLoop = 0;
return (
<Menu style={{ width: "300px", paddingTop: 0, borderRadius: "10px" }}>
<Menu.Item key="201" style={{ backgroundColor: "lightgray", fontWeight: 'bold', borderBottom: "1px solid black", borderRadius: "10px 10px 0 0", cursor: 'default' }}>
Notifications
</Menu.Item>
{dataAlert.map((n, index) => {
currentLoop++;
if (currentLoop < 6) {
return (
<Menu.Item onClick={this.gotoReportAlert} key={index}>
<p style={{ whiteSpace: 'normal', textAlign: 'flex-start' }}>{n.keterangan ? n.keterangan : n.join.alert_keterangan ? n.join.alert_keterangan : "-"}</p>
</Menu.Item>
)
}
})}
{totalAlert > 5 ?
<>
<Menu.Divider></Menu.Divider>
<Menu.Item onClick={this.gotoReportAlert} key="202" style={{ textAlign: 'center', fontWeight: 'bold' }}>
Lihat Selengkapnya
</Menu.Item></> : null}
{totalAlert === 0 ? <Menu.Item key="202" style={{ textAlign: 'center', cursor: 'default' }}>
Tidak ada notifikasi untuk saat ini!
</Menu.Item> : null}
</Menu>
)
}
gotoReportAlert = () => {
this.props.history.replace('/laporan-alert')
}
onReadNotif = (visible) => {
if (!visible) {
const { dataAlert } = this.state
let currentLoop = 0;
let listId = []
dataAlert.map((val, index) => {
currentLoop++;
if (currentLoop < 6) {
listId.push(val.id);
}
});
this.setState({ listReadNotif: listId });
}
}
markAsRead = async () => {
let data = this.state.listReadNotif
const payload = {
"status_view": true
}
let promises = []
let result = []
if (data.length > 0) {
if (parseInt(localStorage.getItem('role_id')) === 1) {
data.map((val, index) => {
let url = ALERT_STATUSVIEW(val)
promises.push(axios.put(url, payload, this.state.config)
.then(res => result.push(res)));
});
} else {
data.map((val, index) => {
let url = ALERTUSER_STATUSVIEW(val)
promises.push(axios.put(url, payload, this.state.config)
.then(res => result.push(res)))
});
}
await Promise.all(promises);
}
this.setState({ listReadNotif: [] }, () => {
});
}
getLogo = () => {
return (
<div style={{ width: '10%', display: 'flex', justifyContent: 'center' }}>
<img
style={{ width: '100%', height: '100%' }}
src={this.getLogoHeaderContent()}
/>
</div>
)
}
// logo_ospro
getHeaderMenu = () => {
const { fullname, u_group } = this.state;
if (u_group == 'kominfo') {
/*return (
<Nav className="d-md-down-none" navbar>
<NavItem className="px-3">
<NavLink to="/dashboard-kominfo" className="nav-link" >Dashboard</NavLink>
</NavItem>
<NavItem className="px-3">
<Link to="/map/view" className="nav-link">Map</Link>
</NavItem>
</Nav>
)*/
return (
<div className="dashboard-title">
<h5>Layanan Telekomunikasi</h5>
</div>
)
}
else {
return (
<Nav className="d-md-down-none" navbar>
{/* <NavItem className="px-3">
<NavLink to="/dashboard" className="nav-link" >Dashboard</NavLink>
</NavItem> */}
{/*<NavItem className="px-3">
<NavLink to="/dashboardb2b" className="nav-link" >Dashboard B2B</NavLink>
</NavItem>
<NavItem className="px-3">
<NavLink to="/dashboardb2c" className="nav-link" >Dashboard B2C</NavLink>
</NavItem>*/}
{/* <NavItem className="px-3">
<Link to="/user" className="nav-link">Users</Link>
</NavItem> */}
{/* <NavItem className="px-3">
<Link to="/map/view" className="nav-link">Map</Link>
</NavItem> */}
</Nav>
)
}
}
render() {
const { children, ...attributes } = this.props;
return (
<React.Fragment>
<AppSidebarToggler className="d-lg-none" display="md" mobile />
{this.getLogo()}
<AppSidebarToggler className="d-md-down-none" display="lg" />
<Nav className="ml-auto" navbar>
{/* <Dropdown onVisibleChange={(visible) => this.onReadNotif(visible)} overlay={this.dropDownMenu} trigger={['click']}>
<NavItem className="d-md-down-none">
<NavLink to="#" className="nav-link"><i className="icon-bell"></i><Badge pill color={this.state.totalAlert > 0 ? "danger" : "default"}>{this.state.totalAlert > 0 ? this.state.totalAlert : null}</Badge></NavLink>
</NavItem>
</Dropdown> */}
</Nav>
</React.Fragment>
);
}
}
DefaultHeader.propTypes = propTypes;
DefaultHeader.defaultProps = defaultProps;
export default DefaultHeader;
import React, { Component } from 'react';
import { NavLink } from 'react-router-dom';
import { Badge, Nav, NavItem } from 'reactstrap';
import PropTypes from 'prop-types';
import { Menu, Dropdown } from 'antd'
import { ALERTUSER_SEARCH, ALERT_SEARCH, ALERTUSER_STATUSVIEW, ALERT_STATUSVIEW, APP_MODE, BASE_SIMPRO_LUMEN_IMAGE } from '../../const/ApiConst';
import { AppAsideToggler, AppNavbarBrand, AppSidebarToggler } from '@coreui/react';
import logo_ospro from '../../assets/img/OSPRO.png'
import axios from 'axios';
import './Default.css'
const propTypes = {
children: PropTypes.node,
};
const defaultProps = {};
class DefaultHeader extends Component {
constructor(props) {
super(props);
this.state = {
fullname: localStorage.getItem('fullname'),
u_group: localStorage.getItem('u_group'),
dataAlert: [],
totalAlert: 0,
listReadNotif: []
}
this.callAlert = "";
}
componentDidMount() {
this.getHeaderMenu();
const token = window.localStorage.getItem('token');
const role = window.localStorage.getItem('role_name');
if (role !== 'Super Admin') {
this.setState({
configApp: JSON.parse(window.localStorage.getItem('configApp')),
});
}
this.setState({
config: {
headers: {
Authorization: `Bearer ${token}`,
'Content-type': `application/json`,
},
},
});
}
getLogoHeaderContent = () => {
const { configApp } = this.state;
const logoHeaderContent = configApp && configApp.logo_header ? configApp.logo_header.content : null;
return logoHeaderContent
? `${BASE_SIMPRO_LUMEN_IMAGE}/${logoHeaderContent}`
: logo_ospro;
};
componentDidUpdate(prevProps, prevState) {
if (this.state.listReadNotif !== prevState.listReadNotif) {
if (this.state.listReadNotif.length > 0) {
this.markAsRead();
}
}
}
componentWillUnmount() {
clearInterval(this.callAlert);
}
getDataAlert = async () => {
let url = '';
let payload = '';
if (parseInt(localStorage.getItem('role_id')) === 1) {
url = ALERT_SEARCH;
payload = {
"paging": { "start": 0, "length": -1 },
"columns": [
{ "name": "status_view", "logic_operator": "=", "value": "false", "operator": "AND" },
],
"joins": [
{ "name": "config_alert", "column_join": "config_alert_id", "column_results": ["nama", "keterangan"] },
{ "name": "laporan_planning", "column_join": "laporan_planning_id", "column_results": ["deskripsi", "status", "jumlah_pekerjaan"] },
{ "name": "m_satuan", "column_join": "satuan_id", "column_results": ["name", "description"] }
],
"orders": { "columns": ["created_at"], "ascending": false }
}
} else {
url = ALERTUSER_SEARCH;
payload = {
"paging": { "start": 0, "length": -1 },
"columns": [
{ "name": "status_view", "logic_operator": "=", "value": "false", "operator": "AND" },
{ "name": "user_id", "logic_operator": "=", "value": localStorage.getItem('user_id'), "operator": "AND" },
],
"joins": [
{ "name": "alert", "column_join": "alert_id", "column_results": ["nama", "keterangan"] },
{ "name": "config_alert", "column_join": "config_alert_id", "column_results": ["nama", "keterangan"] },
{ "name": "laporan_planning", "column_join": "laporan_planning_id", "column_results": ["deskripsi", "status", "jumlah_pekerjaan"] },
{ "name": "m_satuan", "column_join": "satuan_id", "column_results": ["name", "description"] },
{ "name": "m_users", "column_join": "user_id", "column_results": ["name", "username", "email", "phone_number", "gender"] }
],
"orders": { "columns": ["created_at"], "ascending": false }
}
}
if (localStorage.getItem('userConfigAlert')) {
if (parseInt(localStorage.getItem('role_id')) === 1) {
payload['columns'].push({ "name": "config_alert_id", "logic_operator": "IN", "value": localStorage.getItem('userConfigAlert'), "operator": "AND" })
} else {
payload['columns'].push({ "name": "config_alert_id", "logic_operator": "IN", "value": localStorage.getItem('userConfigAlert'), "operator": "AND", "table_name": "alert" })
}
} else {
if (parseInt(localStorage.getItem('role_id')) === 1) {
payload['columns'].push({ "name": "config_alert_id", "logic_operator": "IN", "value": "0", "operator": "AND" })
} else {
payload['columns'].push({ "name": "config_alert_id", "logic_operator": "IN", "value": "0", "operator": "AND", "table_name": "alert" })
}
}
const result = await axios
.post(url, payload, this.state.config)
.then(res => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
this.setState({ dataAlert: result.data.data, totalAlert: result.data.totalRecord });
}
}
dropDownMenu = () => {
const { dataAlert, totalAlert } = this.state
let dataAlertLength = dataAlert.length
let currentLoop = 0;
return (
<Menu style={{ width: "300px", paddingTop: 0, borderRadius: "10px" }}>
<Menu.Item key="201" style={{ backgroundColor: "lightgray", fontWeight: 'bold', borderBottom: "1px solid black", borderRadius: "10px 10px 0 0", cursor: 'default' }}>
Notifications
</Menu.Item>
{dataAlert.map((n, index) => {
currentLoop++;
if (currentLoop < 6) {
return (
<Menu.Item onClick={this.gotoReportAlert} key={index}>
<p style={{ whiteSpace: 'normal', textAlign: 'flex-start' }}>{n.keterangan ? n.keterangan : n.join.alert_keterangan ? n.join.alert_keterangan : "-"}</p>
</Menu.Item>
)
}
})}
{totalAlert > 5 ?
<>
<Menu.Divider></Menu.Divider>
<Menu.Item onClick={this.gotoReportAlert} key="202" style={{ textAlign: 'center', fontWeight: 'bold' }}>
Lihat Selengkapnya
</Menu.Item></> : null}
{totalAlert === 0 ? <Menu.Item key="202" style={{ textAlign: 'center', cursor: 'default' }}>
Tidak ada notifikasi untuk saat ini!
</Menu.Item> : null}
</Menu>
)
}
gotoReportAlert = () => {
this.props.history.replace('/laporan-alert')
}
onReadNotif = (visible) => {
if (!visible) {
const { dataAlert } = this.state
let currentLoop = 0;
let listId = []
dataAlert.map((val, index) => {
currentLoop++;
if (currentLoop < 6) {
listId.push(val.id);
}
});
this.setState({ listReadNotif: listId });
}
}
markAsRead = async () => {
let data = this.state.listReadNotif
const payload = {
"status_view": true
}
let promises = []
let result = []
if (data.length > 0) {
if (parseInt(localStorage.getItem('role_id')) === 1) {
data.map((val, index) => {
let url = ALERT_STATUSVIEW(val)
promises.push(axios.put(url, payload, this.state.config)
.then(res => result.push(res)));
});
} else {
data.map((val, index) => {
let url = ALERTUSER_STATUSVIEW(val)
promises.push(axios.put(url, payload, this.state.config)
.then(res => result.push(res)))
});
}
await Promise.all(promises);
}
this.setState({ listReadNotif: [] }, () => {
});
}
getLogo = () => {
return (
<div style={{ width: '10%', display: 'flex', justifyContent: 'center', paddingLeft:'10px' }}>
<img
style={{ width: '100%', height: '100%' }}
src={this.getLogoHeaderContent()}
/>
</div>
)
}
// logo_ospro
getHeaderMenu = () => {
const { fullname, u_group } = this.state;
if (u_group == 'kominfo') {
/*return (
<Nav className="d-md-down-none" navbar>
<NavItem className="px-3">
<NavLink to="/dashboard-kominfo" className="nav-link" >Dashboard</NavLink>
</NavItem>
<NavItem className="px-3">
<Link to="/map/view" className="nav-link">Map</Link>
</NavItem>
</Nav>
)*/
return (
<div className="dashboard-title">
<h5>Layanan Telekomunikasi</h5>
</div>
)
}
else {
return (
<Nav className="d-md-down-none" navbar>
{/* <NavItem className="px-3">
<NavLink to="/dashboard" className="nav-link" >Dashboard</NavLink>
</NavItem> */}
{/*<NavItem className="px-3">
<NavLink to="/dashboardb2b" className="nav-link" >Dashboard B2B</NavLink>
</NavItem>
<NavItem className="px-3">
<NavLink to="/dashboardb2c" className="nav-link" >Dashboard B2C</NavLink>
</NavItem>*/}
{/* <NavItem className="px-3">
<Link to="/user" className="nav-link">Users</Link>
</NavItem> */}
{/* <NavItem className="px-3">
<Link to="/map/view" className="nav-link">Map</Link>
</NavItem> */}
</Nav>
)
}
}
render() {
const { children, ...attributes } = this.props;
return (
<React.Fragment>
<AppSidebarToggler className="d-lg-none" display="md" mobile />
{this.getLogo()}
<AppSidebarToggler className="d-md-down-none" display="lg" />
<Nav className="ml-auto" navbar>
{/* <Dropdown onVisibleChange={(visible) => this.onReadNotif(visible)} overlay={this.dropDownMenu} trigger={['click']}>
<NavItem className="d-md-down-none">
<NavLink to="#" className="nav-link"><i className="icon-bell"></i><Badge pill color={this.state.totalAlert > 0 ? "danger" : "default"}>{this.state.totalAlert > 0 ? this.state.totalAlert : null}</Badge></NavLink>
</NavItem>
</Dropdown> */}
</Nav>
</React.Fragment>
);
}
}
DefaultHeader.propTypes = propTypes;
DefaultHeader.defaultProps = defaultProps;
export default DefaultHeader;

2
src/routes.js

@ -54,7 +54,7 @@ const DashboardCustomer = React.lazy(() => import('./views/Dashboard/DashboardCu
const DashboardProject = React.lazy(() => import('./views/Dashboard/DashboardProject'));
const DashboardProjectCarousell = React.lazy(() => import('./views/Dashboard/DashboardProjectCarousell'));
const MapMonitoring = React.lazy(() => import('./views/MapMonitoring'));
const Settings = React.lazy(() => import('./views/SimproV2/Settings'));
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 routes = [

31
src/views/Master/MasterCompany/index.js

@ -20,7 +20,11 @@ const config = {
const MasterCompany = ({ params }) => {
const token = localStorage.getItem("token")
const company_id = localStorage.getItem("company_id")
let company_id = '';
const role = window.localStorage.getItem('role_name');
if(role != 'Super Admin') {
company_id = localStorage.getItem("company_id");
}
const HEADER = {
headers: {
"Content-Type": "application/json",
@ -53,7 +57,10 @@ const MasterCompany = ({ params }) => {
const [loading, setLoading] = useState(true);
const pageName = params.name;
const { t } = useTranslation();
const configApp = JSON.parse(window.localStorage.getItem('configApp'));
let configApp = '';
if (role !== 'Super Admin') {
configApp = JSON.parse(window.localStorage.getItem('configApp'));
}
useEffect(() => {
setLoading(true)
getDataCompany()
@ -354,7 +361,9 @@ const MasterCompany = ({ params }) => {
formData.append('ref_id', id);
formData.append('category', 'company_logo_header');
formData.append('files', data);
formData.append('company_name',configApp.company_name);
if(role != 'Super Admin') {
formData.append('company_name',configApp.company_name);
}
await axios
.post(IMAGE_UPLOAD, formData, HEADER_MULTIPART)
@ -368,7 +377,9 @@ const MasterCompany = ({ params }) => {
formData.append('ref_id', id);
formData.append('category', 'company_logo_login');
formData.append('files', data);
formData.append('company_name',configApp.company_name);
if(role != 'Super Admin') {
formData.append('company_name',configApp.company_name);
}
await axios
.post(IMAGE_UPLOAD, formData, HEADER_MULTIPART)
@ -382,7 +393,9 @@ const MasterCompany = ({ params }) => {
formData.append('ref_id', id);
formData.append('category', 'company_favicon');
formData.append('files', data);
formData.append('company_name',configApp.company_name);
if(role != 'Super Admin') {
formData.append('company_name',configApp.company_name);
}
await axios
.post(IMAGE_UPLOAD, formData, HEADER_MULTIPART)
@ -402,7 +415,7 @@ const MasterCompany = ({ params }) => {
// Delete Image Function
const deleteImageHeader = async (id) => {
const URL = IMAGE_DELETE(id, 'company_logo_header', company_id);
const URL = IMAGE_DELETE(id, 'company_logo_header', company_id != '' ? company_id : 'undifined');
await axios
.delete(URL, HEADER)
.then(res => res)
@ -411,7 +424,7 @@ const MasterCompany = ({ params }) => {
};
const deleteImageLogin = async (id) => {
const URL = IMAGE_DELETE(id, 'company_logo_login', company_id);
const URL = IMAGE_DELETE(id, 'company_logo_login', company_id != '' ? company_id : 'undifined');
await axios
.delete(URL, HEADER)
.then(res => res)
@ -420,7 +433,7 @@ const MasterCompany = ({ params }) => {
};
const deleteImageFavicon = async (id) => {
const URL = IMAGE_DELETE(id, 'company_favicon', company_id);
const URL = IMAGE_DELETE(id, 'company_favicon', company_id != '' ? company_id : 'undifined');
await axios
.delete(URL, HEADER)
.then(res => res)
@ -429,7 +442,7 @@ const MasterCompany = ({ params }) => {
};
const deleteImageSlider = async (id) => {
const URL = IMAGE_MULTIPLE_DELETE(id, 'company_slider_login', company_id);
const URL = IMAGE_MULTIPLE_DELETE(id, 'company_slider_login', company_id != '' ? company_id : 'undifined');
await axios
.delete(URL, HEADER)
.then(res => res)

8
src/views/SimproV2/CreatedProyek/DialogDocument.js

@ -12,6 +12,7 @@ import DialogRequest from './FormDocument';
import DialogRequestFolder from './FormFolderDocument';
const DialogDocument = ({ openDialog, closeDialog, toggleDialog, idTask, proyekName }) => {
const token = localStorage.getItem("token")
const role = window.localStorage.getItem('role_name');
const HEADER = {
headers: {
"Content-Type": "application/json",
@ -99,8 +100,11 @@ const DialogDocument = ({ openDialog, closeDialog, toggleDialog, idTask, proyekN
}
const handleShow = (file) => {
const configApp = JSON.parse(window.localStorage.getItem('configApp'));
const urlShow = `${BASE_SIMPRO_LUMEN_FILE_COMPANY(file, configApp.company_name)}`
let configApp = '';
if (role !== 'Super Admin') {
configApp = JSON.parse(window.localStorage.getItem('configApp'));
}
const urlShow = `${BASE_SIMPRO_LUMEN_FILE_COMPANY(file, configApp != '' ? configApp.company_name : 'undifined')}`
window.open(urlShow);
}

12
src/views/SimproV2/CreatedProyek/FormDocument.js

@ -7,7 +7,8 @@ import 'antd/dist/antd.css';
import { NotificationManager } from 'react-notifications';
const DialogRequest = ({ openDialog, closeDialog, toggleDialog, idTask, parentIdNewFolder }) => {
const token = localStorage.getItem("token")
const token = localStorage.getItem("token");
const role = window.localStorage.getItem('role_name');
const HEADER = {
headers: {
"Content-Type": "application/json",
@ -33,12 +34,13 @@ const DialogRequest = ({ openDialog, closeDialog, toggleDialog, idTask, parentId
}
const uploadDokumen = async () => {
const configApp = JSON.parse(window.localStorage.getItem('configApp'));
let configApp = '';
const formData = new FormData;
if (role !== 'Super Admin') {
configApp = JSON.parse(window.localStorage.getItem('configApp'));
formData.append('company_name',configApp.company_name);
}
formData.append('dokumen', file, file.name);
formData.append('company_name',configApp.company_name);
if (parentIdNewFolder > 0) {
formData.append('ref_id', parentIdNewFolder); // folder_id
formData.append('type_dokumen', 'project-document-in-folder');

53
src/views/SimproV2/Settings/Desktop.js

@ -0,0 +1,53 @@
import Index from "./components/MyProfile/Index";
import styles from "./Desktop.module.css";
import Plan from "./components/Plan/Container1";
import React, { useState, useEffect } from 'react';
import { Nav, NavItem, NavLink, TabContent, TabPane } from 'reactstrap';
const Desktop = () => {
const [activeTab, setActiveTab] = useState('tab1')
const [typeTab, setTypeTab] = useState('myprofile')
return (
<main className={styles.myProfile}>
<section className={styles.profile}>
<Nav tabs>
<NavItem>
<NavLink
style={{ borderRadius: typeTab === 'myprofile' ? '15px' : '', backgroundColor: typeTab === 'myprofile' ? '#E0ECF5' : '', color: typeTab === 'myprofile' ? '#48A4F0' : '', fontWeight:'600', border:'none' }}
onClick={() => {
setActiveTab("tab1");
setTypeTab("myprofile");
}}
active={activeTab === "tab1"}
>
My Profile
</NavLink>
</NavItem>
<NavItem>
<NavLink
style={{ borderRadius: typeTab === 'plan' ? '15px' : '', backgroundColor: typeTab === 'plan' ? '#E0ECF5' : '', color: typeTab === 'plan' ? '#48A4F0' : '', fontWeight:'600', border:'none' }}
onClick={() => {
setActiveTab("tab2");
setTypeTab("plan");
}}
active={activeTab === "tab2"}
>
Plan
</NavLink>
</NavItem>
</Nav>
<TabContent activeTab={activeTab} style={{ border:'none' }}>
<TabPane tabId="tab1" style={{ border:'none' }}>
<Index/>
</TabPane>
<TabPane tabId="tab2" style={{ border:'none' }}>
<Plan/>
</TabPane>
</TabContent>
</section>
</main>
);
};
export default Desktop;

23
src/views/SimproV2/Settings/Desktop.module.css

@ -0,0 +1,23 @@
.myProfile,
.profile {
max-width: 100%;
}
.profile {
align-self: stretch;
padding: 15px 30px 30px;
box-sizing: border-box;
gap: 15px 0;
}
.myProfile {
width: 1300px;
border-radius: 30px;
background-color: #fff;
}
@media screen and (max-width: 1050px) {
.profile {
padding-top: 20px;
padding-bottom: 20px;
box-sizing: border-box;
}
}

184
src/views/SimproV2/Settings/DialogForm.js

@ -1,16 +1,15 @@
import React, { useEffect, useState } from 'react'
import {
Modal, ModalHeader, ModalBody, ModalFooter,
Button, Form, FormGroup, Label, Input, Col, Row,
Nav, NavItem, NavLink, TabContent, TabPane
Button, Form, FormGroup, Label, Input, Col, Row,TabContent, TabPane
} from 'reactstrap';
import { Select, DatePicker } from 'antd';
import moment from "moment";
import { BASE_SIMPRO_LUMEN_IMAGE_COMPANY } from '../../../const/ApiConst';
import profile from '../../../assets/img/profile.png'
const { Option } = Select
const DialogForm = ({
openDialog,
closeDialog,
@ -27,28 +26,34 @@ const DialogForm = ({
emailProp,
userNameProp,
refferalCode,
userProfile
userProfile,
imageProfile
}) => {
const token = window.localStorage.getItem('token');
const [typeDialog, setTypeDialog] = useState(typeDialogProp)
const [userName, setUserName] = useState(userNameProp)
const [name, setName] = useState(nameProp)
const [noHp, setNohp] = useState(noHpProp)
const [gender, setGender] = useState(genderProp)
const [address, setAddres] = useState(addressProp)
const [birthdayPlace, setBirthdayplace] = useState(birthdayPlaceProp)
const [birthdayDate, setBirthdaydate] = useState(birthdayDateProp)
const [birthdayDate, setBirthdaydate] = useState(birthdayDateProp && birthdayDateProp != null ? moment(birthdayDateProp) : moment())
const [idNumber, setIdnumber] = useState(idNumberProp)
const [email, setEmail] = useState(emailProp)
const [refferal, setRefferalCode] = useState('')
const [oldPassword, setOldPassword] = useState('')
const [newPassword, setNewPassword] = useState('')
const [newPasswordConfirm, setNewPasswordConfirm] = useState('')
const [activeTab, setActiveTab] = useState('tab1')
console.log('typeDialogProp',typeDialogProp)
const [profileImage, setImageProfile] = useState(null)
const [modalOpen, setModalOpen] = useState(false)
const role = window.localStorage.getItem('role_name');
let configApp = '';
if (role !== 'Super Admin') {
configApp = JSON.parse(window.localStorage.getItem('configApp'));
}
const handleSave = () => {
let data = '';
if (typeDialog === "Personal" && typeDialogProp !== "Refferal") {
if (typeDialogProp === "Personal" && typeDialogProp !== "Refferal") {
data = {
name: name,
phone_number: noHp,
@ -61,11 +66,14 @@ const DialogForm = ({
data.birth_date = birthdayDate;
}
closeDialog('profile', data)
} else if (typeDialog === "Account" && typeDialogProp !== "Refferal") {
} else if (typeDialogProp === "Account" || typeDialogProp === "Settings" && typeDialogProp !== "Refferal") {
data = {
username: userName,
email: email,
password: newPassword,
email: email
}
data.profilePicture = profileImage ? profileImage : null;
if(typeDialogProp === "Settings" && newPassword && oldPassword && newPasswordConfirm) {
data.password = newPassword;
}
closeDialog('profile', data)
} else {
@ -95,6 +103,10 @@ const DialogForm = ({
)
}
const handleDatePickerEnd = (date, dateString) => {
setBirthdaydate(date);
};
function generateRandomString(length) {
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
let result = '';
@ -109,30 +121,38 @@ const DialogForm = ({
setRefferalCode(newReferralCode);
}
const toggleModal = () => {
setModalOpen(!modalOpen);
};
const handleImageClick = async () => {
toggleModal();
};
const renderForm = () => {
return (
<Form>
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Nama</Label>
<Label className="capitalize">Name</Label>
<Input type="text" value={name || nameProp} onChange={(e) => setName(e.target.value)} />
</FormGroup>
<FormGroup>
<Label className="capitalize">ID Number</Label>
<Label className="capitalize">Kode Number</Label>
<Input type="text" value={idNumber || idNumberProp} onChange={(e) => setIdnumber(e.target.value)} />
</FormGroup>
<FormGroup>
<Label className="capitalize">Alamat</Label>
<Label className="capitalize">Address</Label>
<Input type="text" value={address || addressProp} onChange={(e) => setAddres(e.target.value)} />
</FormGroup>
</Col>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Nomor Handphone</Label>
<Label className="capitalize">Telephone</Label>
<Input type="text" value={noHp || noHpProp} onChange={(e) => setNohp(e.target.value)} />
</FormGroup>
@ -146,13 +166,13 @@ const DialogForm = ({
</FormGroup>
<FormGroup>
<Label className="capitalize">Tempat Lahir</Label>
<Label className="capitalize">Place of Birth</Label>
<Input type="text" value={birthdayPlace || birthdayPlaceProp} onChange={(e) => setBirthdayplace(e.target.value)} />
</FormGroup>
<FormGroup>
<Label className="capitalize">Tanggal Lahir</Label>
<DatePicker style={{ width: "100%" }} value={birthdayDate} defaultValue={birthdayDateProp} onChange={(date, dateString) => setBirthdaydate(date)} />
<Label className="capitalize">Date of Birth</Label>
<DatePicker style={{ width: "100%" }} value={birthdayDateProp && birthdayDateProp != null ? moment(birthdayDateProp) : birthdayDate} onChange={handleDatePickerEnd} />
</FormGroup>
</Col>
@ -165,31 +185,47 @@ const DialogForm = ({
return (
<Form>
<Row>
<Col md={6}>
<Col md={12}>
<FormGroup>
<Label className="capitalize" style={{ fontWeight: "bold" }}>Image Profile</Label>
<Input
type="file"
accept="image/*"
onChange={(e) => setImageProfile(e.target.files[0])}
/>
<small onClick={imageProfile ? () => handleImageClick() : ''} style={{ cursor: imageProfile ? "pointer" : "" }}>
<p style={{ textDecoration: imageProfile ? 'underline' : 'none', color: imageProfile ? 'blue' : 'red' }}>
{
imageProfile ? (
"View image"
) : (
"Not found image"
)
}
</p>
</small>
</FormGroup>
<FormGroup>
<Label className="capitalize">Username</Label>
<Input type="text" value={userName || userNameProp} onChange={(e) => setUserName(e.target.value)} />
</FormGroup>
<FormGroup>
<Label className="capitalize">Email</Label>
<Input type="text" value={email || emailProp} onChange={(e) => setEmail(e.target.value)} />
</FormGroup>
</Col>
<Col md={6}>
<Col md={12}>
<FormGroup>
<Label className="capitalize">Old password</Label>
<Label className="capitalize">Old Password</Label>
<Input type="text" value={oldPassword} onChange={(e) => setOldPassword(e.target.value)} />
</FormGroup>
<FormGroup>
<Label className="capitalize">New password</Label>
<Label className="capitalize">New Password</Label>
<Input type="text" value={newPassword} onChange={(e) => setNewPassword(e.target.value)} />
</FormGroup>
<FormGroup>
<Label className="capitalize">Confirm new password</Label>
<Label className="capitalize">Confirm New Password</Label>
<Input type="text" value={newPasswordConfirm} onChange={(e) => setNewPasswordConfirm(e.target.value)} />
</FormGroup>
</Col>
@ -207,12 +243,12 @@ const DialogForm = ({
<Label className="capitalize">Username</Label>
<Input type="text" value={userName || userNameProp} onChange={(e) => setUserName(e.target.value)} />
</FormGroup>
<FormGroup>
<Label className="capitalize">Email</Label>
<Input type="text" value={email || emailProp} onChange={(e) => setEmail(e.target.value)} />
</FormGroup>
</Col>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Email</Label>
<Input type="text" value={email || emailProp} onChange={(e) => setEmail(e.target.value)} />
</FormGroup>
</Col>
</Row>
</Form>
@ -220,56 +256,23 @@ const DialogForm = ({
}
return (
<>
{/* Form */}
<Modal size="lg" isOpen={openDialog} toggle={toggleDialog}>
<ModalHeader className="capitalize" toggle={closeDialog}>
Update {typeDialog == "Personal" ? `Personal` : "Account"} Data
Update {typeDialogProp} {typeDialogProp == 'Refferal' ? ' Code' : ' Data'}
</ModalHeader>
<ModalBody>
{typeDialogProp !== 'Refferal' ? (
<>
<Nav tabs>
<NavItem>
<NavLink
onClick={() => {
setActiveTab("tab1");
setTypeDialog("Personal");
}}
active={activeTab === "tab1"}
>
Personal
</NavLink>
</NavItem>
<NavItem>
<NavLink
onClick={() => {
setActiveTab("tab2");
setTypeDialog("Account");
}}
active={activeTab === "tab2"}
>
Account
</NavLink>
</NavItem>
<NavItem>
<NavLink
onClick={() => {
setActiveTab("tab3");
setTypeDialog("Setting");
}}
active={activeTab === "tab3"}
>
Setting
</NavLink>
</NavItem>
</Nav>
<TabContent activeTab={activeTab}>
<TabPane tabId="tab1">
<TabContent activeTab={typeDialogProp}>
<TabPane tabId="Personal">
{renderForm()}
</TabPane>
<TabPane tabId="tab2">
<TabPane tabId="Settings">
{renderFormAccount()}
</TabPane>
<TabPane tabId="tab3">
<TabPane tabId="Account">
{renderFormSetting()}
</TabPane>
</TabContent>
@ -278,7 +281,7 @@ const DialogForm = ({
<Form>
<Row>
<Col md={12}>
<span style={{ color: "red" }}>*</span> Wajib diisi.
<span style={{ color: "red" }}>*</span> Is required
</Col>
</Row>
<Row>
@ -300,14 +303,33 @@ const DialogForm = ({
)}
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={() => handleSave()}>{typeDialogProp !== 'Refferal' ? typeDialog == "Profile" ? `Profile` : "Save" : "Generate Code"}</Button> {' '}
<Button color="primary" onClick={() => handleSave()}>Save</Button> {' '}
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>Batal</Button>
</ModalFooter>
</Modal>
{/* Image Picture */}
<Modal isOpen={modalOpen} toggle={toggleModal}>
<ModalBody style={{ textAlign:'center' }}>
{
imageProfile ? (
<img
src={
imageProfile ? (
`${BASE_SIMPRO_LUMEN_IMAGE_COMPANY(imageProfile?.image, role != 'Super Admin' ? configApp.company_name : 'undifined')}`
) : profile
}
style={{ maxWidth: "100%" }}
alt="Image Preview"
/>
) : ('Image not found!')
}
</ModalBody>
<ModalFooter>
<Button color="secondary" onClick={toggleModal}>Close</Button>
</ModalFooter>
</Modal>
</>
)
}
export default DialogForm;

69
src/views/SimproV2/Settings/components/MyProfile/Head.module.css

@ -0,0 +1,69 @@
.obejct11 {
width: 55px;
height: 54px;
position: relative;
border-radius: 79.5px;
object-fit: cover;
}
.img {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
padding: 20px 0;
}
.headContent {
position: relative;
font-weight: 600;
}
.headTitle {
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: center;
}
.content {
position: relative;
font-weight: 600;
}
.headSubtitle {
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: center;
font-size: 16px;
color: #777;
}
.head,
.text {
box-sizing: border-box;
display: flex;
}
.text {
width: 1032px;
flex-direction: column;
align-items: flex-start;
justify-content: center;
padding: 20px 0;
gap: 5px 0;
}
.head {
align-self: stretch;
height: 98px;
background-color: #fff;
border: 1px solid #7eacd3;
flex-shrink: 0;
flex-direction: row;
align-items: center;
justify-content: flex-start;
padding: 0 16px 0 14px;
gap: 0 20px;
text-align: left;
font-size: 20px;
color: #333;
}
@media screen and (max-width: 450px) {
.headContent {
font-size: 16px;
}
}

436
src/views/SimproV2/Settings/components/MyProfile/Index.js

@ -0,0 +1,436 @@
import * as XLSX from 'xlsx';
import React, { useState, useEffect, useMemo } from 'react';
import axios from "../../../../../const/interceptorApi"
import { NotificationContainer, NotificationManager } from 'react-notifications';
import { Pagination, Tooltip } from 'antd';
import { USER_EDIT, REFFERAL_ADD, REFFERAL_EDIT, ROLE_SEARCH, USER_SEARCH, IMAGE_UPLOAD, IMAGE_DELETE, IMAGE_GET_BY_ID, BASE_SIMPRO_LUMEN_IMAGE_COMPANY } from '../../../../../const/ApiConst';
import DialogForm from '../../DialogForm'
import styles from "./Index.module.css";
import profile from '../../../../../assets/img/profile.png'
import stylesHead from "./Head.module.css";
import moment from 'moment';
import { Modal, ModalBody, ModalFooter, Button } from 'reactstrap';
const Index = () => {
const token = localStorage.getItem("token")
const user_id = localStorage.getItem("user_id")
let company_id = '', configApp = '';
const role = window.localStorage.getItem('role_name');
if(role !== 'Super Admin') {
company_id = localStorage.getItem("company_id");
configApp = JSON.parse(window.localStorage.getItem('configApp'));
}
const config = {
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`
}
}
const HEADER_MULTIPART = {
headers: {
"Content-Type": "multipart/form-data",
Authorization: `Bearer ${token}`,
},
};
const [openDialog, setOpenDialog] = useState(false)
const [typeDialog, setTypeDialog] = useState('')
const [roleList, setRoleList] = useState([])
const [refferal, setReferralCode] = useState(null)
const [isCopied, setIsCopied] = useState(false)
const [userProfile, setUserprofile] = useState(null)
const [imageProfile, setImageProfile] = useState(null);
const [modalOpen, setModalOpen] = useState(false)
useEffect(() => {
getImageProfle(parseInt(user_id));
getRoleList();
getDataProfileUser();
}, [])
const getDataProfileUser = async () => {
const formData = {
"paging": {"start": 0, "length": 1},
"columns": [
{"name": "id", "logic_operator": "=", "value": parseInt(user_id), "operator": "AND"}
],
"joins": [
{
"name": "m_divisi",
"column_join": "divisi_id",
"column_results": [
"name"
]
},
{
"name": "refferal_code",
"column_join": "discount_id",
"column_results": [
"code"
]
}
]
}
const result = await axios
.post(USER_SEARCH, formData, config)
.then(res => res)
.catch((error) => error.response );
if (result && result.data && result.data.code == 200) {
let dataRes = result.data.data[0];
setUserprofile(dataRes);
if(!dataRes.discount_id || dataRes.discount_id === null || dataRes.discount_id === '') {
saveRefferalCode(dataRes?.username, dataRes?.ktp_number);
} else {
setReferralCode(dataRes.join_second_code);
}
} else {
NotificationManager.error("Gagal Mengambil Data!!", "Failed");
}
}
const handleOpenDialog = (type) => {
setOpenDialog(true)
setTypeDialog(type)
}
const handleCloseDialog = (type, data) => {
if (type === "profile") {
saveProfile(data);
} else if(type === "refferal_code") {
updateRefferal(data);
}
setOpenDialog(false)
}
const saveProfile = async (data) => {
let urlEdit = USER_EDIT(user_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) {
const profilePicture = data.profilePicture;
if (profilePicture && profilePicture != null) {
await deleteImageProfile(
parseInt(user_id),
);
await saveImageProfile(
parseInt(user_id),
profilePicture
);
}
getDataProfileUser()
getImageProfle(user_id)
NotificationManager.success(`Data profile berhasil diedit`, 'Success!!');
} else {
NotificationManager.error(`Data profile gagal di edit`, `Failed!!`);
}
}
// Save Image Function
const saveImageProfile = async (id, data) => {
const formData = new FormData;
formData.append('ref_id', id);
formData.append('category', 'profile_picture');
formData.append('files', data);
if(role !== 'Super Admin') {
formData.append('company_name', configApp.company_name);
}
await axios
.post(IMAGE_UPLOAD, formData, HEADER_MULTIPART)
.then(res => res)
.catch((error) => error.response);
};
// Delete Image Function
const deleteImageProfile = async (id) => {
const URL = IMAGE_DELETE(id, 'profile_picture', company_id != '' ? company_id : 'undifined');
await axios
.delete(URL, config)
.then(res => res)
.catch((error) => error.response);
};
const getImageProfle = async (id) => {
const url = IMAGE_GET_BY_ID(id, "profile_picture");
const result = await axios
.get(url, config)
.then((res) => res)
.catch((err) => err.response);
if (result && result.data && result.data.code === 200) {
setImageProfile(result.data.data);
}
}
const updateRefferal = async (data) => {
let urlEdit = REFFERAL_EDIT(userProfile?.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) {
getDataProfileUser(data.user_id, data.username, data.ktp_number);
NotificationManager.success(`Code refferal berhasil diedit`, 'Success!!');
} else {
NotificationManager.error(`Code refferal gagal di edit`, `Failed!!`);
}
}
const toggleAddDialog = () => {
setOpenDialog(!openDialog)
}
const toggleModal = () => {
setModalOpen(!modalOpen);
};
const handleImageClick = async () => {
toggleModal();
};
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 saveRefferalCode = async (username, ktp_number) => {
const formData = {
'code': username + ktp_number.substring(0, 4),
'amount': 0
}
const result = await axios
.post(REFFERAL_ADD, formData, config)
.then((res) => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
const data = {'discount_id': result.data.data.id};
await saveProfile(data);
} else {
NotificationManager.error('Kode refferal gagal ditambahkan!!', 'Failed');
}
}
function copyToClipboard(text) {
navigator.clipboard.writeText(text).then(() => {
setIsCopied(true);
setTimeout(() => setIsCopied(false), 2000);
}, (err) => {
console.error('Gagal menyalin teks ke clipboard: ', err);
});
}
return (
<>
<NotificationContainer />
<DialogForm
openDialog={openDialog}
closeDialog={handleCloseDialog}
toggleDialog={() => toggleAddDialog}
typeDialogProp={typeDialog}
roleList={roleList}
nameProp={userProfile?.name}
noHpProp={userProfile?.phone_number}
idNumberProp={userProfile?.ktp_number}
genderProp={userProfile?.gender}
divisiProp={userProfile?.join_first_name}
birthdayPlaceProp={userProfile?.birth_place}
birthdayDateProp={userProfile?.birth_date}
addressProp={userProfile?.address}
emailProp={userProfile?.email}
userNameProp={userProfile?.username}
refferalCode={refferal}
userProfile={userProfile}
imageProfile={imageProfile}
/>
<div className={stylesHead.head}>
<div className={stylesHead.img} style={{ cursor:imageProfile ? 'pointer' : '' }} onClick={imageProfile ? () => handleImageClick() : ''}>
<img className={stylesHead.obejct11} src={
imageProfile ? (
`${BASE_SIMPRO_LUMEN_IMAGE_COMPANY(imageProfile?.image, role != 'Super Admin' ? configApp.company_name : 'undifined')}`
) : profile
} />
</div>
<div className={stylesHead.text}>
<div className={stylesHead.headTitle}>
<div className={stylesHead.headContent}>
{userProfile && userProfile.name != null ? userProfile.name : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>}
</div>
</div>
<div className={stylesHead.headSubtitle}>
<div className={stylesHead.content}>
{userProfile && userProfile.username != null ? userProfile.username : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>}
</div>
</div>
</div>
<div className={styles.btnEdit1} style={{ color: '#969696' }} onClick={() => handleOpenDialog('Settings')}>
<div className={styles.icon}>
<i className="fa fa-edit" style={{ fontSize:'16px' }}></i>
</div>
<div className={styles.edit} style={{ fontSize:'16px' }}>Edit</div>
</div>
</div>
<footer className={styles.index1}>
<div className={styles.row}>
<div className={styles.column}>
<div className={styles.text}>
<div className={styles.headTitle}>
<div className={styles.codeReferal}>Refferal Code</div>
</div>
<div className={styles.headSubtitle}>
<div className={styles.ibnu212} style={{ color:'#20A8D8' }}>{refferal ? refferal : 'empty'}</div>
<Tooltip title= {!isCopied ? "Copy Refferal" : "Copied"}>
<span onClick={() => copyToClipboard(refferal ? refferal : 'empty')}>
{isCopied ?
<i className="fa fa-check" style={{ cursor:'pointer' }}></i>
:
<i className="fa fa-clipboard" style={{ cursor:'pointer' }}></i>}
</span>
</Tooltip>
</div>
</div>
<div className={styles.btnEdit1} onClick={() => handleOpenDialog('Refferal')}>
<div className={styles.icon}>
<i className="fa fa-edit"></i>
</div>
<div className={styles.edit}>Edit</div>
</div>
</div>
<div className={styles.row1}>
<div className={styles.column1}>
<div className={styles.accountInformation}>Account Information</div>
<div className={styles.btnEdit2} onClick={() => handleOpenDialog('Account')}>
<div className={styles.icon1}>
<i className="fa fa-edit"></i>
</div>
<div className={styles.edit1}>Edit</div>
</div>
</div>
<div className={styles.column2}>
<div className={styles.frameParent}>
<div className={styles.usernameParent}>
<div className={styles.username}>Username</div>
<div className={styles.ibnu}>
{userProfile && userProfile.username != null ? userProfile.username : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>}
</div>
</div>
<div className={styles.emailParent}>
<div className={styles.email}>Email</div>
<div className={styles.emailContent}>
{userProfile && userProfile.email != null ? userProfile.email : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>}
</div>
</div>
</div>
</div>
</div>
</div>
<div className={styles.row2}>
<div className={styles.row3}>
<div className={styles.personalInformation}>Personal Information</div>
<div className={styles.btnEdit3} onClick={() => handleOpenDialog('Personal')}>
<div className={styles.icon3}>
<i className="fa fa-edit"></i>
</div>
<div className={styles.edit2}>Edit</div>
</div>
</div>
<div className={styles.div}>
<div className={styles.row4}>
<div className={styles.column3}>
<div className={styles.name}>Name</div>
<div className={styles.content}>
{userProfile && userProfile.name != null ? userProfile.name : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>}
</div>
</div>
<div className={styles.column4}>
<div className={styles.noHp}>Telephone</div>
<div className={styles.birthDetailsColumn}>
{userProfile && userProfile.phone_number != null ? userProfile.phone_number : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>}
</div>
</div>
</div>
<div className={styles.row5}>
<div className={styles.column5}>
<div className={styles.idNumber}>Kode Number</div>
<div className={styles.div1}>
{userProfile && userProfile.ktp_number != null ? userProfile.ktp_number : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>}
</div>
</div>
<div className={styles.column6}>
<div className={styles.gender}>Gender</div>
<div className={styles.male}>
{userProfile && userProfile.gender != null ? userProfile.gender : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>}
</div>
</div>
</div>
<div className={styles.row6}>
<div className={styles.column7}>
<div className={styles.division}>Division</div>
<div className={styles.div2}>
{userProfile && userProfile.join_first_name != null ? userProfile.join_first_name : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>}
</div>
</div>
<div className={styles.column8}>
<div className={styles.placeOfBirth}>Place of Birth</div>
<div className={styles.div3}>
{userProfile && userProfile.birth_place != null ? userProfile.birth_place : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>}
</div>
</div>
</div>
<div className={styles.row7}>
<div className={styles.column9}>
<div className={styles.role}>Role</div>
<div className={styles.div4}>
{userProfile && userProfile.employee_type != null ? userProfile.employee_type : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>}
</div>
</div>
<div className={styles.column10}>
<div className={styles.dateOfBirth}>Date of Birth</div>
<div className={styles.div5}>
{userProfile && userProfile.birth_date != null ? userProfile.birth_date : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>}
</div>
</div>
</div>
<div className={styles.row8}>
<div className={styles.column11}>
<div className={styles.address}>Address</div>
<div className={styles.div6}>
{userProfile && userProfile.address != null ? userProfile.address : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>}
</div>
</div>
</div>
</div>
</div>
</footer>
<Modal isOpen={modalOpen} toggle={toggleModal}>
<ModalBody style={{ textAlign:'center' }}>
{
imageProfile ? (
<img
src={
imageProfile ? (
`${BASE_SIMPRO_LUMEN_IMAGE_COMPANY(imageProfile?.image, role != 'Super Admin' ? configApp.company_name : 'undifined')}`
) : profile
}
style={{ maxWidth: "100%" }}
alt="Image Preview"
/>
) : ('Image not found!')
}
</ModalBody>
<ModalFooter>
<Button color="secondary" onClick={toggleModal}>Close</Button>
</ModalFooter>
</Modal>
</>
);
};
export default Index;

563
src/views/SimproV2/Settings/components/MyProfile/Index.module.css

@ -0,0 +1,563 @@
.codeReferal {
position: relative;
font-weight: 600;
}
.headTitle {
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: center;
}
.copyIcon,
.ibnu212 {
position: relative;
}
.copyIcon {
height: 16px;
width: 16px;
overflow: hidden;
flex-shrink: 0;
}
.headSubtitle,
.text {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
gap: 0 10px;
color: #777;
}
.text {
flex: 1;
flex-direction: column;
align-items: flex-start;
justify-content: center;
gap: 5px 0;
min-width: 640px;
max-width: 100%;
color: #333;
}
.copyIcon1 {
height: 24px;
width: 24px;
position: relative;
overflow: hidden;
flex-shrink: 0;
}
.copy {
position: relative;
font-weight: 600;
}
.btnEdit {
border-radius: 20px;
border: 1px solid #969696;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
padding: 5px 11px 5px 9px;
gap: 0 11px;
}
.editTextIcon {
height: 20px;
width: 18px;
position: relative;
}
.icon {
overflow: hidden;
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: flex-start;
padding: 5px 8px;
box-sizing: border-box;
width: 24px;
height: 24px;
}
.edit {
position: relative;
font-weight: 600;
}
.btnEdit1,
.column {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
}
.btnEdit1 {
border-radius: 20px;
border: 1px solid #969696;
padding: 5px 11px 5px 9px;
gap: 0 11px;
cursor: pointer;
}
.column {
align-self: stretch;
background-color: #fff;
border: 1px solid #7eacd3;
box-sizing: border-box;
flex-wrap: wrap;
padding: 20px 21px 20px 19px;
gap: 0 20px;
max-width: 100%;
}
.accountInformation {
position: relative;
font-weight: 600;
}
.icon2 {
height: 20px;
width: 18px;
position: relative;
}
.icon1 {
overflow: hidden;
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: flex-start;
padding: 5px 8px;
box-sizing: border-box;
width: 24px;
height: 24px;
}
.edit1 {
position: relative;
font-weight: 600;
}
.btnEdit2,
.column1 {
display: flex;
flex-direction: row;
}
.btnEdit2 {
border-radius: 20px;
border: 1px solid #969696;
align-items: center;
justify-content: flex-start;
padding: 5px 11px 5px 9px;
gap: 0 11px;
color: #969696;
cursor: pointer;
}
.column1 {
align-self: stretch;
align-items: flex-start;
justify-content: space-between;
gap: 20px;
}
.ibnu,
.username {
position: relative;
}
.username {
font-weight: 500;
}
.ibnu {
color: #777;
}
.usernameParent {
flex: 1;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
gap: 10px 0;
min-width: 378px;
max-width: 100%;
}
.email {
position: relative;
font-weight: 500;
}
.emailContent {
position: relative;
color: #777;
white-space: nowrap;
}
.emailParent,
.frameParent {
display: flex;
align-items: flex-start;
justify-content: flex-start;
max-width: 100%;
}
.emailParent {
flex: 1;
flex-direction: column;
gap: 10px 0;
min-width: 378px;
}
.frameParent {
align-self: stretch;
flex-direction: row;
flex-wrap: wrap;
padding: 0 1px 0 0;
box-sizing: border-box;
gap: 0 37px;
}
.column2,
.row,
.row1 {
align-self: stretch;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
max-width: 100%;
}
.row1 {
background-color: #fff;
border: 1px solid #7eacd3;
box-sizing: border-box;
padding: 20px 21px 20px 19px;
gap: 10px 0;
color: #333;
}
.row {
gap: 15px 0;
}
.personalInformation {
position: relative;
font-weight: 500;
}
.vectorIcon {
height: 20px;
width: 18px;
position: relative;
}
.icon3 {
overflow: hidden;
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: flex-start;
padding: 5px 8px;
box-sizing: border-box;
width: 24px;
height: 24px;
}
.edit2 {
position: relative;
font-weight: 600;
}
.btnEdit3,
.row3 {
display: flex;
flex-direction: row;
}
.btnEdit3 {
border-radius: 20px;
border: 1px solid #969696;
align-items: center;
justify-content: flex-start;
padding: 5px 11px 5px 9px;
gap: 0 11px;
color: #969696;
cursor: pointer;
}
.row3 {
align-self: stretch;
align-items: flex-start;
justify-content: space-between;
gap: 20px;
}
.name {
position: relative;
font-weight: 500;
}
.content {
position: relative;
color: #777;
}
.column3 {
flex: 1;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
gap: 10px 0;
min-width: 378px;
max-width: 100%;
}
.noHp {
position: relative;
font-weight: 500;
}
.birthDetailsColumn {
position: relative;
color: #777;
}
.column4,
.row4 {
display: flex;
align-items: flex-start;
justify-content: flex-start;
max-width: 100%;
}
.column4 {
flex: 1;
flex-direction: column;
gap: 10px 0;
min-width: 378px;
}
.row4 {
align-self: stretch;
flex-direction: row;
flex-wrap: wrap;
padding: 0 1px 0 0;
box-sizing: border-box;
gap: 0 37px;
}
.div1,
.idNumber {
position: relative;
}
.idNumber {
font-weight: 500;
}
.div1 {
color: #777;
}
.column5 {
flex: 1;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
gap: 10px 0;
min-width: 378px;
max-width: 100%;
}
.gender,
.male {
position: relative;
}
.gender {
font-weight: 500;
}
.male {
color: #777;
}
.column6,
.row5 {
display: flex;
align-items: flex-start;
justify-content: flex-start;
max-width: 100%;
}
.column6 {
flex: 1;
flex-direction: column;
gap: 10px 0;
min-width: 378px;
}
.row5 {
align-self: stretch;
flex-direction: row;
flex-wrap: wrap;
padding: 0 1px 0 0;
box-sizing: border-box;
gap: 0 37px;
}
.div2,
.division {
position: relative;
}
.division {
font-weight: 500;
}
.div2 {
color: #777;
}
.column7 {
flex: 1;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
gap: 10px 0;
min-width: 378px;
max-width: 100%;
}
.placeOfBirth {
position: relative;
font-weight: 500;
}
.div3 {
position: relative;
color: #777;
}
.column8,
.row6 {
display: flex;
align-items: flex-start;
justify-content: flex-start;
max-width: 100%;
}
.column8 {
flex: 1;
flex-direction: column;
gap: 10px 0;
min-width: 378px;
}
.row6 {
align-self: stretch;
flex-direction: row;
flex-wrap: wrap;
padding: 0 1px 0 0;
box-sizing: border-box;
gap: 0 37px;
}
.div4,
.role {
position: relative;
}
.role {
font-weight: 500;
}
.div4 {
color: #777;
}
.column9 {
flex: 1;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
gap: 10px 0;
min-width: 378px;
max-width: 100%;
}
.dateOfBirth {
position: relative;
font-weight: 500;
}
.div5 {
position: relative;
color: #777;
}
.column10,
.row7 {
display: flex;
align-items: flex-start;
justify-content: flex-start;
max-width: 100%;
}
.column10 {
flex: 1;
flex-direction: column;
gap: 10px 0;
min-width: 378px;
}
.row7 {
align-self: stretch;
flex-direction: row;
flex-wrap: wrap;
padding: 0 1px 0 0;
box-sizing: border-box;
gap: 0 37px;
}
.address {
font-weight: 500;
}
.address,
.div6 {
position: relative;
}
.div6 {
color: #777;
}
.column11,
.row8 {
display: flex;
align-items: flex-start;
justify-content: flex-start;
max-width: 100%;
}
.column11 {
flex: 1;
flex-direction: column;
gap: 10px 0;
}
.row8 {
align-self: stretch;
flex-direction: row;
}
.div {
gap: 20px 0;
}
.div,
.index1,
.row2 {
align-self: stretch;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
max-width: 100%;
}
.row2 {
background-color: #fff;
border: 1px solid #7eacd3;
box-sizing: border-box;
padding: 20px 21px 20px 19px;
gap: 10px 0;
color: #333;
}
.index1 {
gap: 15px 0;
text-align: left;
font-size: 16px;
color: #969696;
}
@media screen and (max-width: 1050px) {
.text {
min-width: 100%;
}
}
@media screen and (max-width: 750px) {
.emailParent,
.usernameParent {
min-width: 100%;
}
.frameParent {
gap: 0 37px;
}
.column3,
.column4 {
min-width: 100%;
}
.row4 {
gap: 0 37px;
}
.column5,
.column6 {
min-width: 100%;
}
.row5 {
gap: 0 37px;
}
.column7,
.column8 {
min-width: 100%;
}
.row6 {
gap: 0 37px;
}
.column10,
.column9 {
min-width: 100%;
}
.row7,
.row8 {
gap: 0 37px;
}
}
@media screen and (max-width: 450px) {
.column1,
.row3 {
flex-wrap: wrap;
}
}

65
src/views/SimproV2/Settings/components/Plan/Column.js

@ -0,0 +1,65 @@
import { useMemo } from "react";
import styles from "./Column.module.css";
const Column = ({
date,
currentPlanFrame,
textFrame,
currentPlanText,
text,
daysFrame,
propHeight,
propMinHeight,
propFlex,
propHeight1,
propFlex1,
propWidth,
}) => {
const columnStyle = useMemo(() => {
return {
height: propHeight,
};
}, [propHeight]);
const headStyle = useMemo(() => {
return {
minHeight: propMinHeight,
flex: propFlex,
};
}, [propMinHeight, propFlex]);
const dateStyle = useMemo(() => {
return {
height: propHeight1,
flex: propFlex1,
width: propWidth,
};
}, [propHeight1, propFlex1, propWidth]);
return (
<div className={styles.column} style={columnStyle}>
<div className={styles.head} style={headStyle}>
<div className={styles.date} style={dateStyle}>
{date}
</div>
</div>
<div className={styles.head1}>
<div className={styles.currentPlanFrame}>{currentPlanFrame}</div>
</div>
<div className={styles.head2}>
<div className={styles.textFrame}>{textFrame}</div>
</div>
<div className={styles.head3}>
<div className={styles.currentPlanText}>{currentPlanText}</div>
</div>
<div className={styles.head4}>
<div className={styles.text}>{text}</div>
</div>
<div className={styles.head5}>
<div className={styles.daysFrame}>{daysFrame}</div>
</div>
</div>
);
};
export default Column;

114
src/views/SimproV2/Settings/components/Plan/Column.module.css

@ -0,0 +1,114 @@
.date,
.head {
max-width: 100%;
}
.date {
height: 19px;
flex: 1;
position: relative;
line-height: 22px;
font-weight: 600;
display: inline-block;
overflow: hidden;
text-overflow: ellipsis;
}
.head {
align-self: stretch;
border-bottom: 1px solid #d8d8d8;
box-sizing: border-box;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 8px;
min-height: 59px;
color: #969696;
}
.currentPlanFrame {
position: relative;
line-height: 22px;
}
.head1 {
align-self: stretch;
background-color: #fdfdfd;
border-bottom: 1px solid #d8d8d8;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 16px 8px;
white-space: nowrap;
}
.textFrame {
position: relative;
line-height: 22px;
}
.head2 {
align-self: stretch;
background-color: #fdfdfd;
border-bottom: 1px solid #d8d8d8;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 16px 8px;
white-space: nowrap;
}
.currentPlanText {
position: relative;
line-height: 22px;
}
.head3 {
align-self: stretch;
background-color: #fdfdfd;
border-bottom: 1px solid #d8d8d8;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 16px 8px;
white-space: nowrap;
}
.text {
position: relative;
line-height: 22px;
}
.head4 {
align-self: stretch;
background-color: #fdfdfd;
border-bottom: 1px solid #d8d8d8;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 16px 8px;
white-space: nowrap;
}
.daysFrame {
position: relative;
line-height: 22px;
}
.column,
.head5 {
display: flex;
align-items: center;
}
.head5 {
align-self: stretch;
background-color: #fdfdfd;
border-bottom: 1px solid #d8d8d8;
flex-direction: row;
justify-content: center;
padding: 16px 8px;
white-space: nowrap;
}
.column {
width: 400px;
flex-shrink: 0;
flex-direction: column;
justify-content: flex-start;
text-align: center;
font-size: 18px;
color: #333;
font-family: Roboto;
}

69
src/views/SimproV2/Settings/components/Plan/Container.js

@ -0,0 +1,69 @@
import Column from "./Column";
import styles from "./Container.module.css";
import React, { useState, useEffect } from 'react';
const Container = () => {
return (
<section className={styles.container}>
<div className={styles.headText}>
<div className={styles.paymentHistory}>Payment history</div>
</div>
<div className={styles.table}>
<Column
date="Date"
currentPlanFrame="9-02-2024 07:47:29"
textFrame="9-01-2024 07:47:29"
currentPlanText="9-12-2023 07:47:29"
text="9-11-2023 07:47:29"
daysFrame="9-10-2023 07:47:29"
/>
<Column
date="Amount"
currentPlanFrame="250k"
textFrame="250k"
currentPlanText="250k"
text="250k"
daysFrame="250k"
propHeight="333.4px"
propMinHeight="unset"
propFlex="1"
propHeight1="unset"
propFlex1="unset"
propWidth="64px"
/>
<div className={styles.column}>
<div className={styles.head}>
<div className={styles.status}>Status</div>
</div>
<div className={styles.head1}>
<div className={styles.successfulWrapper}>
<div className={styles.successful}>Successful</div>
</div>
</div>
<div className={styles.head2}>
<div className={styles.successfulContainer}>
<div className={styles.successful1}>Successful</div>
</div>
</div>
<div className={styles.head3}>
<div className={styles.successfulFrame}>
<div className={styles.successful2}>Successful</div>
</div>
</div>
<div className={styles.head4}>
<div className={styles.frameDiv}>
<div className={styles.successful3}>Successful</div>
</div>
</div>
<div className={styles.head5}>
<div className={styles.successfulWrapper1}>
<div className={styles.successful4}>Successful</div>
</div>
</div>
</div>
</div>
</section>
);
};
export default Container;

229
src/views/SimproV2/Settings/components/Plan/Container.module.css

@ -0,0 +1,229 @@
.paymentHistory {
position: relative;
font-weight: 500;
}
.headText {
align-self: stretch;
height: 34px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
}
.status {
width: 53px;
position: relative;
line-height: 22px;
font-weight: 600;
display: inline-block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.head {
align-self: stretch;
flex: 1;
border-bottom: 1px solid #d8d8d8;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 8px;
color: #969696;
}
.successful {
flex: 1;
position: relative;
line-height: 22px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.head1,
.successfulWrapper {
box-sizing: border-box;
display: flex;
flex-direction: row;
align-items: center;
}
.successfulWrapper {
width: 109px;
border-radius: 20px;
background-color: #17c13e;
justify-content: flex-start;
padding: 3px 10px;
}
.head1 {
align-self: stretch;
height: 54.8px;
background-color: #fdfdfd;
border-bottom: 1px solid #d8d8d8;
justify-content: center;
padding: 16px 8px;
}
.successful1 {
flex: 1;
position: relative;
line-height: 22px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.head2,
.successfulContainer {
box-sizing: border-box;
display: flex;
flex-direction: row;
align-items: center;
}
.successfulContainer {
width: 109px;
border-radius: 20px;
background-color: #17c13e;
justify-content: flex-start;
padding: 3px 10px;
}
.head2 {
align-self: stretch;
height: 54.8px;
background-color: #fdfdfd;
border-bottom: 1px solid #d8d8d8;
justify-content: center;
padding: 16px 8px;
}
.successful2 {
flex: 1;
position: relative;
line-height: 22px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.head3,
.successfulFrame {
box-sizing: border-box;
display: flex;
flex-direction: row;
align-items: center;
}
.successfulFrame {
width: 109px;
border-radius: 20px;
background-color: #17c13e;
justify-content: flex-start;
padding: 3px 10px;
}
.head3 {
align-self: stretch;
height: 54.8px;
background-color: #fdfdfd;
border-bottom: 1px solid #d8d8d8;
justify-content: center;
padding: 16px 8px;
}
.successful3 {
flex: 1;
position: relative;
line-height: 22px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.frameDiv,
.head4 {
box-sizing: border-box;
display: flex;
flex-direction: row;
align-items: center;
}
.frameDiv {
width: 109px;
border-radius: 20px;
background-color: #17c13e;
justify-content: flex-start;
padding: 3px 10px;
}
.head4 {
align-self: stretch;
height: 54.8px;
background-color: #fdfdfd;
border-bottom: 1px solid #d8d8d8;
justify-content: center;
padding: 16px 8px;
}
.successful4 {
flex: 1;
position: relative;
line-height: 22px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.head5,
.successfulWrapper1 {
box-sizing: border-box;
display: flex;
flex-direction: row;
align-items: center;
}
.successfulWrapper1 {
width: 109px;
border-radius: 20px;
background-color: #17c13e;
justify-content: flex-start;
padding: 3px 10px;
}
.head5 {
align-self: stretch;
height: 54.8px;
background-color: #fdfdfd;
border-bottom: 1px solid #d8d8d8;
justify-content: center;
padding: 16px 8px;
}
.column,
.container,
.table {
display: flex;
justify-content: flex-start;
}
.column {
height: 333.4px;
width: 400px;
flex-shrink: 0;
flex-direction: column;
align-items: center;
color: #fdfdfd;
}
.container,
.table {
align-items: flex-start;
max-width: 100%;
}
.table {
width: 1200px;
border-radius: 4px;
background-color: #fdfdfd;
overflow-x: auto;
flex-direction: row;
text-align: center;
font-size: 18px;
}
.container {
width: 1240px;
background-color: #fff;
border: 1px solid #7eacd3;
box-sizing: border-box;
flex-direction: column;
padding: 20px 21px 20px 19px;
gap: 10px 0;
text-align: left;
font-size: 20px;
color: #333;
font-family: Roboto;
}
@media screen and (max-width: 450px) {
.paymentHistory {
font-size: 16px;
}
}

226
src/views/SimproV2/Settings/components/Plan/Container1.js

@ -0,0 +1,226 @@
import styles from "./Container1.module.css";
import React, { useState, useEffect } from 'react';
import axios from "../../../../../const/interceptorApi"
import { PROYEK_SEARCH, TRANSACTION_SEARCH, STORAGE_LIMIT_INFORMATION } from '../../../../../const/ApiConst';
import { NotificationContainer, NotificationManager } from 'react-notifications';
import moment from "moment";
const Container1 = () => {
const token = localStorage.getItem("token")
const user_id = localStorage.getItem("user_id")
let company_id = '', configApp = '';
const role = window.localStorage.getItem('role_name');
const [totalPage, setTotalPage] = useState(0);
const [transaction, setTransaction] = useState([]);
const [storage, setLimitInformation] = useState(0)
const currentDate = new Date();
const givenDate = new Date(transaction.exp_ospro);
const createdDate = new Date(transaction.created_at)
const differenceInMillis = givenDate.getTime() - currentDate.getTime();
const differenceInDays = Math.floor(differenceInMillis / (1000 * 60 * 60 * 24));
if(role !== 'Super Admin') {
company_id = localStorage.getItem("company_id");
configApp = JSON.parse(window.localStorage.getItem('configApp'));
}
const config = {
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`
}
}
useEffect(()=>{
getDataProyek();
getDataTransaction();
getLimitInformation();
},[])
const getDataProyek = async () => {
const payload = {
"columns": [
{"name": "company_id", "logic_operator": "=", "value": parseInt(company_id), "operator": "AND"}
],
"select": [
"nama",
"mulai_proyek",
"akhir_proyek",
"company_id"
],
};
const result = await axios
.post(PROYEK_SEARCH, payload, config)
.then((res) => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
setTotalPage(result.data.totalRecord);
} else {
NotificationManager.error("Gagal Mengambil Data!!", "Failed");
}
};
const getDataTransaction = async () => {
const formData = {
"paging": {"start": 0, "length": 1},
"columns": [
{"name": "company_id", "logic_operator": "=", "value": parseInt(company_id), "operator": "AND"}
],
"select": [
"company_id",
"type_paket",
"amount",
"exp_ospro",
"pay_date",
"created_at"
]
}
const result = await axios
.post(TRANSACTION_SEARCH, formData, config)
.then(res => res)
.catch((error) => error.response );
if (result && result.data && result.data.code == 200) {
let dataRes = result.data.data[0];
setTransaction(dataRes);
} else {
NotificationManager.error("Gagal Mengambil Data!!", "Failed");
}
}
const getLimitInformation = async () => {
const url = STORAGE_LIMIT_INFORMATION(configApp.company_name);
const result = await axios
.get(url, config)
.then((res) => res)
.catch((error) => error.response);
if (result.data) {
setLimitInformation(result.data);
} else {
NotificationManager.error("Gagal Mengambil Data!!", "Failed");
}
}
return (
<section className={styles.container}>
<div className={styles.projectFrame}>
<div className={styles.currentPlan}>Current Plan</div>
<div className={styles.div}>
<div className={styles.div1}>
<div className={styles.text}>
<div className={styles.payNowCancelFrame}>
<div className={styles.yourCurrentPlan}>
Your Current Plan is <span style={{ color: "#59b4c3", fontWeight: '600' }}>{transaction.type_paket}</span>
</div>
<div className={styles.aSimpleStart}>
A simple start for everyone
</div>
</div>
</div>
<div className={styles.notificationText}>
<div className={styles.activeUntilMarc092024Parent}>
<div className={styles.activeUntilMarc}>
Active until <span style={{ color: "#59b4c3", fontWeight: '600' }}>{moment(transaction.exp_ospro).format('DD MMMM, YYYY')}</span>
</div>
<div className={styles.weWillSend}>
We will send you a notification upon Subscription expiration
</div>
</div>
</div>
<div className={styles.notificationText1}>
<div className={styles.paymentOf250kParent}>
<div className={styles.paymentOf250k}>Payment of 250k</div>
<div className={styles.paymentIsDue}>
Payment is due 9 March, 2024
</div>
</div>
</div>
</div>
<div className={styles.containerFrame}>
<button className={styles.payNowCancelSubscribe}>
<div className={styles.payNow}>Pay Now</div>
</button>
<button className={styles.payNowCancelSubscribe1}>
<div className={styles.cancelSubscription}>
Cancel Subscription
</div>
</button>
</div>
</div>
</div>
<div className={styles.daysOfDaysFrame}>
<div className={styles.days}>
<div className={styles.frameYourCurrentPlan}>
<div className={styles.days1}>Days</div>
<div className={styles.of30Days}>{30 - Math.abs(differenceInDays)} of 30 Days</div>
</div>
<div className={styles.rectangleFrame}>
<div className={styles.rectangleFrameChild} />
<div style={{
width: `${(400 * (30 - Math.abs(differenceInDays))) / 30}px`,
position: 'relative',
backgroundColor: ((30 - Math.abs(differenceInDays)) >= 0 && (30 - Math.abs(differenceInDays)) <= 10) ? '#59b4c3' :
((30 - Math.abs(differenceInDays)) >= 11 && (30 - Math.abs(differenceInDays)) <= 20) ? '#ffa447' :
'#FF4747',
zIndex:'1',
padding:'5px',
borderRadius:'15px'
}}>
</div>
</div>
<div className={styles.daysRemainingUntil}>
{Math.abs(differenceInDays)} days remaining until your plan requires update
</div>
</div>
<div className={styles.days2}>
<div className={styles.storageParent}>
<div className={styles.storage}>Storage</div>
<div className={styles.of500mb}>{storage} of {transaction.type_paket === 'Basic' ? 500 : 50}MB</div>
</div>
<div className={styles.rectangleParent}>
<div className={styles.frameChild} />
<div style={{
width: `${(400 * storage) / (transaction.type_paket === 'Basic' ? 500 : 50)}px`,
position: 'relative',
backgroundColor: (storage >= 0 && storage <= (transaction.type_paket === 'Basic' ? 166.67 : 16.67)) ? '#59b4c3' :
(storage >= (transaction.type_paket === 'Basic' ? 166.68 : 16.68) && storage <= (transaction.type_paket === 'Basic' ? 333.33 : 33.33)) ? '#ffa447' :
'#FF4747',
zIndex:'1',
padding:'5px',
borderRadius:'15px'
}}>
</div>
</div>
<div className={styles.storageRemainingUntil}>
{((storage / (transaction.type_paket === 'Basic' ? 500 : 50)) * 100).toFixed(2)}% storage remaining until your plan requires update
</div>
</div>
<div className={styles.days3}>
<div className={styles.projectParent}>
<div className={styles.project}>Project</div>
<div className={styles.of10Project}>{parseInt(totalPage)} of {transaction.type_paket === "Basic" ? "10" : "1"} Project</div>
</div>
<div className={styles.rectangleGroup}>
<div className={styles.frameInner} />
<div style={{
width: `${(400 * parseInt(totalPage)) / (parseInt(transaction.type_paket === "Basic" ? 10 : 1))}px`,
position: 'relative',
backgroundColor: transaction.type_paket === "Basic" ? (parseInt(totalPage) >= 0 && parseInt(totalPage) <= 3) ? '#59b4c3' :
(parseInt(totalPage) >= 4 && parseInt(totalPage) <= 7) ? '#ffa447' :
'#FF4747' : '#FF4747',
zIndex:'1',
padding:'5px',
borderRadius:'15px'
}}>
</div>
</div>
<div className={styles.projectRemainingUntil}>
{parseInt(transaction.type_paket === "Basic" ? 10 : 1) - (parseInt(totalPage))} Project remaining until your plan requires update
</div>
</div>
</div>
</section>
);
};
export default Container1;

356
src/views/SimproV2/Settings/components/Plan/Container1.module.css

@ -0,0 +1,356 @@
.currentPlan,
.yourCurrentPlan {
position: relative;
font-weight: 500;
}
.aSimpleStart {
position: relative;
color: #777;
}
.payNowCancelFrame,
.text {
display: flex;
align-items: flex-start;
max-width: 100%;
}
.payNowCancelFrame {
flex: 1;
flex-direction: column;
justify-content: flex-start;
gap: 10px 0;
}
.text {
align-self: stretch;
flex-direction: row;
justify-content: center;
}
.activeUntilMarc {
position: relative;
font-weight: 500;
}
.weWillSend {
align-self: stretch;
position: relative;
color: #777;
}
.activeUntilMarc092024Parent,
.notificationText {
display: flex;
align-items: flex-start;
max-width: 100%;
}
.activeUntilMarc092024Parent {
flex: 1;
flex-direction: column;
justify-content: flex-start;
gap: 10px 0;
}
.notificationText {
align-self: stretch;
flex-direction: row;
justify-content: center;
}
.paymentIsDue,
.paymentOf250k {
position: relative;
font-weight: 500;
}
.paymentIsDue {
color: #777;
}
.div1,
.notificationText1,
.paymentOf250kParent {
display: flex;
align-items: flex-start;
max-width: 100%;
}
.paymentOf250kParent {
flex: 1;
flex-direction: column;
justify-content: flex-start;
gap: 10px 0;
}
.div1,
.notificationText1 {
align-self: stretch;
flex-direction: row;
justify-content: center;
}
.div1 {
flex-direction: column;
justify-content: flex-start;
gap: 20px 0;
}
.payNow {
position: relative;
font-size: 18px;
font-weight: 500;
color: #fdfdfd;
text-align: left;
}
.payNowCancelSubscribe {
cursor: pointer;
border: 0;
padding: 10px 15px;
background-color: #20a8d8;
border-radius: 15px;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
white-space: nowrap;
}
.payNowCancelSubscribe:hover {
background-color: #058fbf;
}
.cancelSubscription {
position: relative;
font-size: 18px;
font-weight: 500;
color: #ea5455;
text-align: left;
}
.payNowCancelSubscribe1 {
cursor: pointer;
border: 0;
padding: 10px 15px;
background-color: #fce4e4;
border-radius: 15px;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
white-space: nowrap;
}
.payNowCancelSubscribe1:hover {
background-color: #e3c9c9;
}
.containerFrame,
.div,
.projectFrame {
display: flex;
justify-content: flex-start;
}
.containerFrame {
flex-direction: row;
align-items: center;
gap: 0 20px;
}
.div,
.projectFrame {
flex-direction: column;
align-items: flex-start;
max-width: 100%;
}
.div {
align-self: stretch;
gap: 20px 0;
font-size: 16px;
}
.projectFrame {
flex: 1;
gap: 15px 0;
min-width: 390px;
flex-shrink: 0;
}
.days1,
.of30Days {
position: relative;
}
.frameYourCurrentPlan {
width: 400px;
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: space-between;
gap: 20px;
}
.rectangleFrameChild {
width: 600px;
position: relative;
background-color: #d9d9d9;
display: none;
}
.daysRemaining,
.rectangleFrame,
.rectangleFrameChild {
width: 400px;
border-radius: 5px;
max-width: 100%;
}
.rectangleFrame {
height: 10px;
background-color: #d9d9d9;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
padding: 0 1px;
box-sizing: border-box;
}
.daysRemainingUntil {
position: relative;
display: inline-block;
max-width: 100%;
}
.days {
width: 600px;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
gap: 5px 0;
}
.of500mb,
.storage {
position: relative;
}
.storageParent {
width: 400px;
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: space-between;
gap: 20px;
}
.frameChild {
width: 600px;
position: relative;
background-color: #d9d9d9;
display: none;
}
.frameChild,
.frameItem,
.rectangleParent {
width: 400px;
border-radius: 5px;
max-width: 100%;
}
.frameItem {
width: 539.1px;
position: relative;
background-color: #ffa447;
z-index: 1;
}
.rectangleParent {
height: 10px;
background-color: #d9d9d9;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
padding: 0 1px;
box-sizing: border-box;
}
.storageRemainingUntil {
align-self: stretch;
position: relative;
}
.days2 {
width: 600px;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
gap: 5px 0;
}
.of10Project,
.project {
position: relative;
}
.projectParent {
width: 400px;
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: space-between;
gap: 20px;
}
.frameInner {
width: 200px;
position: relative;
background-color: #d9d9d9;
display: none;
}
.frameInner,
.rectangleDiv,
.rectangleGroup {
width: 400px;
border-radius: 5px;
max-width: 100%;
}
.rectangleGroup {
height: 10px;
background-color: #d9d9d9;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
}
.projectRemainingUntil {
align-self: stretch;
position: relative;
}
.container,
.days3,
.daysOfDaysFrame {
display: flex;
justify-content: flex-start;
}
.days3 {
width: 600px;
flex-direction: column;
align-items: flex-start;
gap: 5px 0;
}
.container,
.daysOfDaysFrame {
box-sizing: border-box;
max-width: 100%;
}
.daysOfDaysFrame {
flex: 1;
flex-direction: column;
align-items: flex-start;
padding: 0 0 31px;
gap: 20px 0;
min-width: 490px;
flex-shrink: 0;
font-size: 16px;
color: #777;
}
.container {
width: 1240px;
background-color: #fff;
border: 1px solid #7eacd3;
overflow: hidden;
flex-direction: row;
flex-wrap: wrap;
align-items: flex-end;
padding: 26px 21px 20px 19px;
row-gap: 20px;
text-align: left;
font-size: 20px;
color: #333;
}
@media screen and (max-width: 675px) {
.notificationText,
.notificationText1,
.text {
gap: 0 37px;
}
.daysOfDaysFrame,
.projectFrame {
min-width: 100%;
overflow-x: auto;
}
}
@media screen and (max-width: 450px) {
.currentPlan {
font-size: 16px;
}
.containerFrame {
flex-wrap: wrap;
}
}

5
src/views/SimproV2/Settings/index.js

@ -105,7 +105,7 @@ const Setting = ({ params }) => {
} else {
NotificationManager.error(`Code refferal gagal di edit`, `Failed!!`);
}
}
}
const toggleAddDialog = () => {
setOpenDialog(!openDialog)
@ -141,7 +141,7 @@ const Setting = ({ params }) => {
} else {
NotificationManager.error("Gagal Mengambil Data!!", "Failed");
}
};
}
const getDataRefferal = async (user_id, username, ktp_number) => {
const url = REFFERAL_GET_ID(user_id);
@ -181,7 +181,6 @@ const Setting = ({ params }) => {
});
}
return (
<div>
<NotificationContainer />

Loading…
Cancel
Save