From 56004337ddadcdb3e1a0024b8fb9f5b4653e7fda Mon Sep 17 00:00:00 2001 From: wahyuun Date: Fri, 23 Feb 2024 13:38:26 +0700 Subject: [PATCH 1/6] profile --- src/views/SimproV2/Settings/Desktop.js | 51 ++ .../SimproV2/Settings/Desktop.module.css | 23 + src/views/SimproV2/Settings/DialogForm.js | 117 ++-- .../Settings/components/Head.module.css | 69 +++ .../SimproV2/Settings/components/Index1.js | 342 +++++++++++ .../Settings/components/Index1.module.css | 563 ++++++++++++++++++ .../Settings/components/SideProfile.js | 19 + .../components/SideProfile.module.css | 44 ++ src/views/SimproV2/Settings/index.js | 5 +- 9 files changed, 1152 insertions(+), 81 deletions(-) create mode 100644 src/views/SimproV2/Settings/Desktop.js create mode 100644 src/views/SimproV2/Settings/Desktop.module.css create mode 100644 src/views/SimproV2/Settings/components/Head.module.css create mode 100644 src/views/SimproV2/Settings/components/Index1.js create mode 100644 src/views/SimproV2/Settings/components/Index1.module.css create mode 100644 src/views/SimproV2/Settings/components/SideProfile.js create mode 100644 src/views/SimproV2/Settings/components/SideProfile.module.css diff --git a/src/views/SimproV2/Settings/Desktop.js b/src/views/SimproV2/Settings/Desktop.js new file mode 100644 index 0000000..a534f35 --- /dev/null +++ b/src/views/SimproV2/Settings/Desktop.js @@ -0,0 +1,51 @@ +import SideProfile from "./components/SideProfile"; +import Index1 from "./components/Index1"; +import styles from "./Desktop.module.css"; +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 ( +
+
+ + + + + + + Tab Kedua + + +
+
+ ); +}; + +export default Desktop; diff --git a/src/views/SimproV2/Settings/Desktop.module.css b/src/views/SimproV2/Settings/Desktop.module.css new file mode 100644 index 0000000..bdb39c7 --- /dev/null +++ b/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; + } +} diff --git a/src/views/SimproV2/Settings/DialogForm.js b/src/views/SimproV2/Settings/DialogForm.js index 0f36cc1..d0c4015 100644 --- a/src/views/SimproV2/Settings/DialogForm.js +++ b/src/views/SimproV2/Settings/DialogForm.js @@ -1,16 +1,12 @@ 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"; const { Option } = Select - - const DialogForm = ({ openDialog, closeDialog, @@ -29,26 +25,23 @@ const DialogForm = ({ refferalCode, userProfile }) => { - 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 handleSave = () => { let data = ''; - if (typeDialog === "Personal" && typeDialogProp !== "Refferal") { + if (typeDialogProp === "Personal" && typeDialogProp !== "Refferal") { data = { name: name, phone_number: noHp, @@ -61,11 +54,13 @@ 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 + } + if(typeDialogProp === "Settings" && newPassword && oldPassword && newPasswordConfirm) { + data.password = newPassword; } closeDialog('profile', data) } else { @@ -95,6 +90,10 @@ const DialogForm = ({ ) } + const handleDatePickerEnd = (date, dateString) => { + setBirthdaydate(date); + }; + function generateRandomString(length) { const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; let result = ''; @@ -115,24 +114,24 @@ const DialogForm = ({ - + setName(e.target.value)} /> - + setIdnumber(e.target.value)} /> - + setAddres(e.target.value)} /> - + setNohp(e.target.value)} /> @@ -146,13 +145,13 @@ const DialogForm = ({ - + setBirthdayplace(e.target.value)} /> - - setBirthdaydate(date)} /> + + @@ -165,7 +164,7 @@ const DialogForm = ({ return (
- + setUserName(e.target.value)} /> @@ -177,19 +176,19 @@ const DialogForm = ({ setEmail(e.target.value)} /> - + - + setOldPassword(e.target.value)} /> - + setNewPassword(e.target.value)} /> - + setNewPasswordConfirm(e.target.value)} /> @@ -207,12 +206,12 @@ const DialogForm = ({ setUserName(e.target.value)} /> - - - - - setEmail(e.target.value)} /> - + + + + + setEmail(e.target.value)} /> +
@@ -222,54 +221,19 @@ const DialogForm = ({ return ( - Update {typeDialog == "Personal" ? `Personal` : "Account"} Data + Update {typeDialogProp} {typeDialogProp == 'Refferal' ? ' Code' : ' Data'} {typeDialogProp !== 'Refferal' ? ( <> - - - + + {renderForm()} - + {renderFormAccount()} - + {renderFormSetting()} @@ -278,7 +242,7 @@ const DialogForm = ({
- * Wajib diisi. + * Is required @@ -300,14 +264,11 @@ const DialogForm = ({ )} - {' '} + {' '} ) - - - } export default DialogForm; diff --git a/src/views/SimproV2/Settings/components/Head.module.css b/src/views/SimproV2/Settings/components/Head.module.css new file mode 100644 index 0000000..aa70ca9 --- /dev/null +++ b/src/views/SimproV2/Settings/components/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; +} +.ibnuHamdani { + position: relative; + font-weight: 600; +} +.headTitle { + display: flex; + flex-direction: row; + align-items: flex-start; + justify-content: center; +} +.ibnu { + 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) { + .ibnuHamdani { + font-size: 16px; + } +} diff --git a/src/views/SimproV2/Settings/components/Index1.js b/src/views/SimproV2/Settings/components/Index1.js new file mode 100644 index 0000000..33eeab9 --- /dev/null +++ b/src/views/SimproV2/Settings/components/Index1.js @@ -0,0 +1,342 @@ +import * as XLSX from 'xlsx'; +import React, { useState, useEffect, useMemo } from 'react'; +import SweetAlert from 'react-bootstrap-sweetalert'; +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 } from '../../../../const/ApiConst'; +import DialogForm from '../DialogForm' +import styles from "./Index1.module.css"; +import stylesModule from "./Index1.module.css"; +import profile from '../../../../assets/img/profile.png' +import stylesHead from "./Head.module.css"; +import moment from 'moment'; +import { Form } from 'reactstrap'; + +const Index1 = () => { + const token = localStorage.getItem("token") + const id = localStorage.getItem("user_id") + + const config = { + headers: { + "Content-Type": "application/json", + "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) + + useEffect(() => { + getRoleList(); + getDataProfileUser(); + }, []) + + const getDataProfileUser = async () => { + const formData = { + "paging": {"start": 0, "length": -1}, + "columns": [ + {"name": "id", "logic_operator": "=", "value": parseInt(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) { + saveRefferalCode(dataRes?.id, 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(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() + NotificationManager.success(`Data profile berhasil diedit`, 'Success!!'); + } else { + NotificationManager.error(`Data profile gagal di edit`, `Failed!!`); + } + } + + 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 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 (user_id, 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) { + await getDataProfileUser(user_id, username, ktp_number); + } + } + + function copyToClipboard(text) { + navigator.clipboard.writeText(text).then(() => { + setIsCopied(true); + setTimeout(() => setIsCopied(false), 2000); + }, (err) => { + console.error('Gagal menyalin teks ke clipboard: ', err); + }); + } + + return ( + <> + + 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} + /> +
+
+ +
+
+
+
+ {userProfile && userProfile.name != null ? userProfile.name : empty} +
+
+
+
+ {userProfile && userProfile.username != null ? userProfile.username : empty} +
+
+
+
handleOpenDialog('Settings')}> +
+ +
+
Edit
+
+
+
+
+
+
+
+
Refferal Code
+
+
+
{refferal ? refferal : 'empty'}
+ + copyToClipboard(refferal ? refferal : 'empty')}> + {isCopied ? + + : + } + + +
+
+
handleOpenDialog('Refferal')}> +
+ +
+
Edit
+
+
+
+
+
Account Information
+
handleOpenDialog('Account')}> +
+ +
+
Edit
+
+
+
+
+
+
Username
+
+ {userProfile && userProfile.username != null ? userProfile.username : empty} +
+
+
+
Email
+
+ {userProfile && userProfile.email != null ? userProfile.email : empty} +
+
+
+
+
+
+
+
+
Personal Information
+
handleOpenDialog('Personal')}> +
+ +
+
Edit
+
+
+
+
+
+
Name
+
+ {userProfile && userProfile.name != null ? userProfile.name : empty} +
+
+
+
Telephone
+
+ {userProfile && userProfile.phone_number != null ? userProfile.phone_number : empty} +
+
+
+
+
+
Kode Number
+
+ {userProfile && userProfile.ktp_number != null ? userProfile.ktp_number : empty} +
+
+
+
Gender
+
+ {userProfile && userProfile.gender != null ? userProfile.gender : empty} +
+
+
+
+
+
Division
+
+ {userProfile && userProfile.join_first_name != null ? userProfile.join_first_name : empty} +
+
+
+
Place of Birth
+
+ {userProfile && userProfile.birth_place != null ? userProfile.birth_place : empty} +
+
+
+
+
+
Role
+
+ {userProfile && userProfile.employee_type != null ? userProfile.employee_type : empty} +
+
+
+
Date of Birth
+
+ {userProfile && userProfile.birth_date != null ? userProfile.birth_date : empty} +
+
+
+
+
+
Address
+
+ {userProfile && userProfile.address != null ? userProfile.address : empty} +
+
+
+
+
+
+ + ); +}; + +export default Index1; diff --git a/src/views/SimproV2/Settings/components/Index1.module.css b/src/views/SimproV2/Settings/components/Index1.module.css new file mode 100644 index 0000000..d2d8ccb --- /dev/null +++ b/src/views/SimproV2/Settings/components/Index1.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; +} +.ibnuhamdaniintegrasiautamac { + 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; +} +.ibnuHamdani { + 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; + } +} diff --git a/src/views/SimproV2/Settings/components/SideProfile.js b/src/views/SimproV2/Settings/components/SideProfile.js new file mode 100644 index 0000000..20ab653 --- /dev/null +++ b/src/views/SimproV2/Settings/components/SideProfile.js @@ -0,0 +1,19 @@ +import "antd/dist/antd.min.css"; +import { Button } from "antd"; +import styles from "./SideProfile.module.css"; +import React, { useState, useEffect, useMemo } from 'react'; + +const SideProfile = () => { + return ( +
+
+
+
My Profile
+
Plan
+
+
+
+ ); +}; + +export default SideProfile; diff --git a/src/views/SimproV2/Settings/components/SideProfile.module.css b/src/views/SimproV2/Settings/components/SideProfile.module.css new file mode 100644 index 0000000..a7ca95a --- /dev/null +++ b/src/views/SimproV2/Settings/components/SideProfile.module.css @@ -0,0 +1,44 @@ +.button { + white-space: nowrap; +} +.plan { + position: relative; + font-weight: 600; +} +.button1 { + flex: 1; + align-items: center; + padding: 15px; + box-sizing: border-box; +} +.button1, +.side, +.sideProfile { + display: flex; + flex-direction: row; + justify-content: flex-start; + max-width: 100%; +} +.side { + flex: 1; + background-color: #fff; + align-items: flex-start; + gap: 0 15px; +} +.sideProfile { + align-self: stretch; + align-items: center; + padding: 30px; + box-sizing: border-box; + top: 0; + z-index: 99; + position: sticky; + text-align: left; + font-size: 20px; + color: #777; +} +@media screen and (max-width: 1200px) { + .side { + display: none; + } +} diff --git a/src/views/SimproV2/Settings/index.js b/src/views/SimproV2/Settings/index.js index 0476aed..f2ba9a8 100644 --- a/src/views/SimproV2/Settings/index.js +++ b/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 (
From 9c92502dbc823b7cb751f4342e68b929f6e83129 Mon Sep 17 00:00:00 2001 From: wahyuun Date: Fri, 23 Feb 2024 13:47:10 +0700 Subject: [PATCH 2/6] ignore super admin --- src/views/Master/MasterCompany/index.js | 31 +++++++++++++------ .../SimproV2/CreatedProyek/DialogDocument.js | 8 +++-- .../SimproV2/CreatedProyek/FormDocument.js | 12 ++++--- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/views/Master/MasterCompany/index.js b/src/views/Master/MasterCompany/index.js index 9a06900..a7bab4f 100644 --- a/src/views/Master/MasterCompany/index.js +++ b/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) diff --git a/src/views/SimproV2/CreatedProyek/DialogDocument.js b/src/views/SimproV2/CreatedProyek/DialogDocument.js index 69830d0..8dded7e 100644 --- a/src/views/SimproV2/CreatedProyek/DialogDocument.js +++ b/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); } diff --git a/src/views/SimproV2/CreatedProyek/FormDocument.js b/src/views/SimproV2/CreatedProyek/FormDocument.js index 71edd49..f333717 100644 --- a/src/views/SimproV2/CreatedProyek/FormDocument.js +++ b/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'); From ecf9cc925d1927b170f17be5f24fd5e55059cc4c Mon Sep 17 00:00:00 2001 From: wahyuun Date: Fri, 23 Feb 2024 13:54:31 +0700 Subject: [PATCH 3/6] add route profile --- src/routes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes.js b/src/routes.js index eb71b0f..6fafb24 100644 --- a/src/routes.js +++ b/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 = [ From 82b2703dd2077ebab33ecee693483001cfba0ab5 Mon Sep 17 00:00:00 2001 From: wahyuun Date: Tue, 27 Feb 2024 16:48:56 +0700 Subject: [PATCH 4/6] add endpoint --- src/const/ApiConst.js | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/const/ApiConst.js b/src/const/ApiConst.js index 1401b07..9c07bd7 100644 --- a/src/const/ApiConst.js +++ b/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) => { From 9dbdd1c1af4c79a0f9084c06605b5a21fc66c216 Mon Sep 17 00:00:00 2001 From: wahyuun Date: Tue, 27 Feb 2024 16:49:12 +0700 Subject: [PATCH 5/6] add padding in logo --- src/containers/DefaultLayout/DefaultHeader.js | 592 +++++++++--------- 1 file changed, 296 insertions(+), 296 deletions(-) diff --git a/src/containers/DefaultLayout/DefaultHeader.js b/src/containers/DefaultLayout/DefaultHeader.js index b04fb21..de15875 100644 --- a/src/containers/DefaultLayout/DefaultHeader.js +++ b/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 ( - - - Notifications - - {dataAlert.map((n, index) => { - currentLoop++; - if (currentLoop < 6) { - return ( - -

{n.keterangan ? n.keterangan : n.join.alert_keterangan ? n.join.alert_keterangan : "-"}

-
- ) - } - })} - {totalAlert > 5 ? - <> - - - Lihat Selengkapnya - : null} - {totalAlert === 0 ? - Tidak ada notifikasi untuk saat ini! - : null} -
- ) - } - - 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 ( -
- -
- ) - } - // logo_ospro - getHeaderMenu = () => { - const { fullname, u_group } = this.state; - if (u_group == 'kominfo') { - /*return ( - - )*/ - - - return ( -
-
Layanan Telekomunikasi
-
- ) - } - else { - return ( - - ) - } - } - - render() { - - const { children, ...attributes } = this.props; - - return ( - - - {this.getLogo()} - - - - ); - } -} - -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 ( + + + Notifications + + {dataAlert.map((n, index) => { + currentLoop++; + if (currentLoop < 6) { + return ( + +

{n.keterangan ? n.keterangan : n.join.alert_keterangan ? n.join.alert_keterangan : "-"}

+
+ ) + } + })} + {totalAlert > 5 ? + <> + + + Lihat Selengkapnya + : null} + {totalAlert === 0 ? + Tidak ada notifikasi untuk saat ini! + : null} +
+ ) + } + + 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 ( +
+ +
+ ) + } + // logo_ospro + getHeaderMenu = () => { + const { fullname, u_group } = this.state; + if (u_group == 'kominfo') { + /*return ( + + )*/ + + + return ( +
+
Layanan Telekomunikasi
+
+ ) + } + else { + return ( + + ) + } + } + + render() { + + const { children, ...attributes } = this.props; + + return ( + + + {this.getLogo()} + + + + ); + } +} + +DefaultHeader.propTypes = propTypes; +DefaultHeader.defaultProps = defaultProps; + +export default DefaultHeader; From 7f388aa0eed60cd68b412e2fda0c49acdacdbcff Mon Sep 17 00:00:00 2001 From: wahyuun Date: Tue, 27 Feb 2024 16:49:33 +0700 Subject: [PATCH 6/6] redesign profile --- src/views/SimproV2/Settings/Desktop.js | 18 +- src/views/SimproV2/Settings/DialogForm.js | 71 +++- .../{ => MyProfile}/Head.module.css | 6 +- .../{Index1.js => MyProfile/Index.js} | 152 ++++++-- .../Index.module.css} | 4 +- .../Settings/components/Plan/Column.js | 65 ++++ .../components/Plan/Column.module.css | 114 ++++++ .../Settings/components/Plan/Container.js | 69 ++++ .../components/Plan/Container.module.css | 229 +++++++++++ .../Settings/components/Plan/Container1.js | 226 +++++++++++ .../components/Plan/Container1.module.css | 356 ++++++++++++++++++ .../Settings/components/SideProfile.js | 19 - .../components/SideProfile.module.css | 44 --- 13 files changed, 1263 insertions(+), 110 deletions(-) rename src/views/SimproV2/Settings/components/{ => MyProfile}/Head.module.css (96%) rename src/views/SimproV2/Settings/components/{Index1.js => MyProfile/Index.js} (72%) rename src/views/SimproV2/Settings/components/{Index1.module.css => MyProfile/Index.module.css} (99%) create mode 100644 src/views/SimproV2/Settings/components/Plan/Column.js create mode 100644 src/views/SimproV2/Settings/components/Plan/Column.module.css create mode 100644 src/views/SimproV2/Settings/components/Plan/Container.js create mode 100644 src/views/SimproV2/Settings/components/Plan/Container.module.css create mode 100644 src/views/SimproV2/Settings/components/Plan/Container1.js create mode 100644 src/views/SimproV2/Settings/components/Plan/Container1.module.css delete mode 100644 src/views/SimproV2/Settings/components/SideProfile.js delete mode 100644 src/views/SimproV2/Settings/components/SideProfile.module.css diff --git a/src/views/SimproV2/Settings/Desktop.js b/src/views/SimproV2/Settings/Desktop.js index a534f35..d3feacb 100644 --- a/src/views/SimproV2/Settings/Desktop.js +++ b/src/views/SimproV2/Settings/Desktop.js @@ -1,6 +1,6 @@ -import SideProfile from "./components/SideProfile"; -import Index1 from "./components/Index1"; +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'; @@ -14,6 +14,7 @@ const Desktop = () => { - - - + + + - - Tab Kedua + + diff --git a/src/views/SimproV2/Settings/DialogForm.js b/src/views/SimproV2/Settings/DialogForm.js index d0c4015..d968fc7 100644 --- a/src/views/SimproV2/Settings/DialogForm.js +++ b/src/views/SimproV2/Settings/DialogForm.js @@ -5,6 +5,9 @@ import { } 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 = ({ @@ -23,7 +26,8 @@ const DialogForm = ({ emailProp, userNameProp, refferalCode, - userProfile + userProfile, + imageProfile }) => { const [userName, setUserName] = useState(userNameProp) const [name, setName] = useState(nameProp) @@ -38,6 +42,14 @@ const DialogForm = ({ const [oldPassword, setOldPassword] = useState('') const [newPassword, setNewPassword] = useState('') const [newPasswordConfirm, setNewPasswordConfirm] = useState('') + 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 = ''; @@ -59,6 +71,7 @@ const DialogForm = ({ username: userName, email: email } + data.profilePicture = profileImage ? profileImage : null; if(typeDialogProp === "Settings" && newPassword && oldPassword && newPasswordConfirm) { data.password = newPassword; } @@ -108,6 +121,14 @@ const DialogForm = ({ setRefferalCode(newReferralCode); } + const toggleModal = () => { + setModalOpen(!modalOpen); + }; + + const handleImageClick = async () => { + toggleModal(); + }; + const renderForm = () => { return ( @@ -119,7 +140,7 @@ const DialogForm = ({ - + setIdnumber(e.target.value)} /> @@ -165,11 +186,29 @@ const DialogForm = ({ + + + setImageProfile(e.target.files[0])} + /> + handleImageClick() : ''} style={{ cursor: imageProfile ? "pointer" : "" }}> +

+ { + imageProfile ? ( + "View image" + ) : ( + "Not found image" + ) + } +

+
+
setUserName(e.target.value)} /> - @@ -181,12 +220,10 @@ const DialogForm = ({ setOldPassword(e.target.value)} /> - setNewPassword(e.target.value)} /> - setNewPasswordConfirm(e.target.value)} /> @@ -219,6 +256,8 @@ const DialogForm = ({ } return ( + <> + {/* Form */} Update {typeDialogProp} {typeDialogProp == 'Refferal' ? ' Code' : ' Data'} @@ -268,6 +307,28 @@ const DialogForm = ({ + {/* Image Picture */} + + + { + imageProfile ? ( + Image Preview + ) : ('Image not found!') + } + + + + + + ) } diff --git a/src/views/SimproV2/Settings/components/Head.module.css b/src/views/SimproV2/Settings/components/MyProfile/Head.module.css similarity index 96% rename from src/views/SimproV2/Settings/components/Head.module.css rename to src/views/SimproV2/Settings/components/MyProfile/Head.module.css index aa70ca9..0a6548b 100644 --- a/src/views/SimproV2/Settings/components/Head.module.css +++ b/src/views/SimproV2/Settings/components/MyProfile/Head.module.css @@ -12,7 +12,7 @@ justify-content: flex-start; padding: 20px 0; } -.ibnuHamdani { +.headContent { position: relative; font-weight: 600; } @@ -22,7 +22,7 @@ align-items: flex-start; justify-content: center; } -.ibnu { +.content { position: relative; font-weight: 600; } @@ -63,7 +63,7 @@ color: #333; } @media screen and (max-width: 450px) { - .ibnuHamdani { + .headContent { font-size: 16px; } } diff --git a/src/views/SimproV2/Settings/components/Index1.js b/src/views/SimproV2/Settings/components/MyProfile/Index.js similarity index 72% rename from src/views/SimproV2/Settings/components/Index1.js rename to src/views/SimproV2/Settings/components/MyProfile/Index.js index 33eeab9..e6e51a4 100644 --- a/src/views/SimproV2/Settings/components/Index1.js +++ b/src/views/SimproV2/Settings/components/MyProfile/Index.js @@ -1,45 +1,57 @@ import * as XLSX from 'xlsx'; import React, { useState, useEffect, useMemo } from 'react'; -import SweetAlert from 'react-bootstrap-sweetalert'; -import axios from "../../../../const/interceptorApi" +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 } from '../../../../const/ApiConst'; -import DialogForm from '../DialogForm' -import styles from "./Index1.module.css"; -import stylesModule from "./Index1.module.css"; -import profile from '../../../../assets/img/profile.png' +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 { Form } from 'reactstrap'; - -const Index1 = () => { - const token = localStorage.getItem("token") - const id = localStorage.getItem("user_id") +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}, + "paging": {"start": 0, "length": 1}, "columns": [ - {"name": "id", "logic_operator": "=", "value": parseInt(id), "operator": "AND"} + {"name": "id", "logic_operator": "=", "value": parseInt(user_id), "operator": "AND"} ], "joins": [ { @@ -65,8 +77,8 @@ const Index1 = () => { if (result && result.data && result.data.code == 200) { let dataRes = result.data.data[0]; setUserprofile(dataRes); - if(!dataRes.discount_id || dataRes.discount_id === null) { - saveRefferalCode(dataRes?.id, dataRes?.username, dataRes?.ktp_number); + if(!dataRes.discount_id || dataRes.discount_id === null || dataRes.discount_id === '') { + saveRefferalCode(dataRes?.username, dataRes?.ktp_number); } else { setReferralCode(dataRes.join_second_code); } @@ -90,19 +102,65 @@ const Index1 = () => { } const saveProfile = async (data) => { - let urlEdit = USER_EDIT(userProfile?.id) + 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 @@ -121,6 +179,14 @@ const Index1 = () => { setOpenDialog(!openDialog) } + const toggleModal = () => { + setModalOpen(!modalOpen); + }; + + const handleImageClick = async () => { + toggleModal(); + }; + const getRoleList = async () => { const formData = { "paging": { "start": 0, "length": -1 }, @@ -135,7 +201,7 @@ const Index1 = () => { } } - const saveRefferalCode = async (user_id, username, ktp_number) => { + const saveRefferalCode = async (username, ktp_number) => { const formData = { 'code': username + ktp_number.substring(0, 4), 'amount': 0 @@ -145,7 +211,10 @@ const Index1 = () => { .then((res) => res) .catch((error) => error.response); if (result && result.data && result.data.code == 200) { - await getDataProfileUser(user_id, username, ktp_number); + const data = {'discount_id': result.data.data.id}; + await saveProfile(data); + } else { + NotificationManager.error('Kode refferal gagal ditambahkan!!', 'Failed'); } } @@ -179,28 +248,33 @@ const Index1 = () => { userNameProp={userProfile?.username} refferalCode={refferal} userProfile={userProfile} + imageProfile={imageProfile} />
-
- +
handleImageClick() : ''}> +
-
+
{userProfile && userProfile.name != null ? userProfile.name : empty}
-
+
{userProfile && userProfile.username != null ? userProfile.username : empty}
-
handleOpenDialog('Settings')}> -
+
handleOpenDialog('Settings')}> +
-
Edit
+
Edit
@@ -249,7 +323,7 @@ const Index1 = () => {
Email
-
+
{userProfile && userProfile.email != null ? userProfile.email : empty}
@@ -271,7 +345,7 @@ const Index1 = () => {
Name
-
+
{userProfile && userProfile.name != null ? userProfile.name : empty}
@@ -335,8 +409,28 @@ const Index1 = () => {
+ + + { + imageProfile ? ( + Image Preview + ) : ('Image not found!') + } + + + + + ); }; -export default Index1; +export default Index; diff --git a/src/views/SimproV2/Settings/components/Index1.module.css b/src/views/SimproV2/Settings/components/MyProfile/Index.module.css similarity index 99% rename from src/views/SimproV2/Settings/components/Index1.module.css rename to src/views/SimproV2/Settings/components/MyProfile/Index.module.css index d2d8ccb..769266a 100644 --- a/src/views/SimproV2/Settings/components/Index1.module.css +++ b/src/views/SimproV2/Settings/components/MyProfile/Index.module.css @@ -171,7 +171,7 @@ position: relative; font-weight: 500; } -.ibnuhamdaniintegrasiautamac { +.emailContent { position: relative; color: #777; white-space: nowrap; @@ -267,7 +267,7 @@ position: relative; font-weight: 500; } -.ibnuHamdani { +.content { position: relative; color: #777; } diff --git a/src/views/SimproV2/Settings/components/Plan/Column.js b/src/views/SimproV2/Settings/components/Plan/Column.js new file mode 100644 index 0000000..1b12b09 --- /dev/null +++ b/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 ( +
+
+
+ {date} +
+
+
+
{currentPlanFrame}
+
+
+
{textFrame}
+
+
+
{currentPlanText}
+
+
+
{text}
+
+
+
{daysFrame}
+
+
+ ); +}; + +export default Column; diff --git a/src/views/SimproV2/Settings/components/Plan/Column.module.css b/src/views/SimproV2/Settings/components/Plan/Column.module.css new file mode 100644 index 0000000..b75cf60 --- /dev/null +++ b/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; +} diff --git a/src/views/SimproV2/Settings/components/Plan/Container.js b/src/views/SimproV2/Settings/components/Plan/Container.js new file mode 100644 index 0000000..bb40141 --- /dev/null +++ b/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 ( +
+
+
Payment history
+
+
+ + +
+
+
Status
+
+
+
+
Successful
+
+
+
+
+
Successful
+
+
+
+
+
Successful
+
+
+
+
+
Successful
+
+
+
+
+
Successful
+
+
+
+
+
+ ); +}; + +export default Container; diff --git a/src/views/SimproV2/Settings/components/Plan/Container.module.css b/src/views/SimproV2/Settings/components/Plan/Container.module.css new file mode 100644 index 0000000..e067faf --- /dev/null +++ b/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; + } +} diff --git a/src/views/SimproV2/Settings/components/Plan/Container1.js b/src/views/SimproV2/Settings/components/Plan/Container1.js new file mode 100644 index 0000000..85d06c3 --- /dev/null +++ b/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 ( +
+
+
Current Plan
+
+
+
+
+
+ Your Current Plan is {transaction.type_paket} +
+
+ A simple start for everyone +
+
+
+
+
+
+ Active until {moment(transaction.exp_ospro).format('DD MMMM, YYYY')} +
+
+ We will send you a notification upon Subscription expiration +
+
+
+
+
+
Payment of 250k
+
+ Payment is due 9 March, 2024 +
+
+
+
+
+ + +
+
+
+
+
+
+
Days
+
{30 - Math.abs(differenceInDays)} of 30 Days
+
+
+
+
= 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' + }}> +
+
+
+ {Math.abs(differenceInDays)} days remaining until your plan requires update +
+
+
+
+
Storage
+
{storage} of {transaction.type_paket === 'Basic' ? 500 : 50}MB
+
+
+
+
= 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' + }}> +
+
+
+ {((storage / (transaction.type_paket === 'Basic' ? 500 : 50)) * 100).toFixed(2)}% storage remaining until your plan requires update +
+
+
+
+
Project
+
{parseInt(totalPage)} of {transaction.type_paket === "Basic" ? "10" : "1"} Project
+
+
+
+
= 0 && parseInt(totalPage) <= 3) ? '#59b4c3' : + (parseInt(totalPage) >= 4 && parseInt(totalPage) <= 7) ? '#ffa447' : + '#FF4747' : '#FF4747', + zIndex:'1', + padding:'5px', + borderRadius:'15px' + }}> +
+
+
+ {parseInt(transaction.type_paket === "Basic" ? 10 : 1) - (parseInt(totalPage))} Project remaining until your plan requires update +
+
+
+
+ ); +}; + +export default Container1; diff --git a/src/views/SimproV2/Settings/components/Plan/Container1.module.css b/src/views/SimproV2/Settings/components/Plan/Container1.module.css new file mode 100644 index 0000000..4327bda --- /dev/null +++ b/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; + } +} diff --git a/src/views/SimproV2/Settings/components/SideProfile.js b/src/views/SimproV2/Settings/components/SideProfile.js deleted file mode 100644 index 20ab653..0000000 --- a/src/views/SimproV2/Settings/components/SideProfile.js +++ /dev/null @@ -1,19 +0,0 @@ -import "antd/dist/antd.min.css"; -import { Button } from "antd"; -import styles from "./SideProfile.module.css"; -import React, { useState, useEffect, useMemo } from 'react'; - -const SideProfile = () => { - return ( -
-
-
-
My Profile
-
Plan
-
-
-
- ); -}; - -export default SideProfile; diff --git a/src/views/SimproV2/Settings/components/SideProfile.module.css b/src/views/SimproV2/Settings/components/SideProfile.module.css deleted file mode 100644 index a7ca95a..0000000 --- a/src/views/SimproV2/Settings/components/SideProfile.module.css +++ /dev/null @@ -1,44 +0,0 @@ -.button { - white-space: nowrap; -} -.plan { - position: relative; - font-weight: 600; -} -.button1 { - flex: 1; - align-items: center; - padding: 15px; - box-sizing: border-box; -} -.button1, -.side, -.sideProfile { - display: flex; - flex-direction: row; - justify-content: flex-start; - max-width: 100%; -} -.side { - flex: 1; - background-color: #fff; - align-items: flex-start; - gap: 0 15px; -} -.sideProfile { - align-self: stretch; - align-items: center; - padding: 30px; - box-sizing: border-box; - top: 0; - z-index: 99; - position: sticky; - text-align: left; - font-size: 20px; - color: #777; -} -@media screen and (max-width: 1200px) { - .side { - display: none; - } -}