Browse Source

redesign profile

pull/1/head
wahyuun 9 months ago
parent
commit
7f388aa0ee
  1. 18
      src/views/SimproV2/Settings/Desktop.js
  2. 71
      src/views/SimproV2/Settings/DialogForm.js
  3. 6
      src/views/SimproV2/Settings/components/MyProfile/Head.module.css
  4. 152
      src/views/SimproV2/Settings/components/MyProfile/Index.js
  5. 4
      src/views/SimproV2/Settings/components/MyProfile/Index.module.css
  6. 65
      src/views/SimproV2/Settings/components/Plan/Column.js
  7. 114
      src/views/SimproV2/Settings/components/Plan/Column.module.css
  8. 69
      src/views/SimproV2/Settings/components/Plan/Container.js
  9. 229
      src/views/SimproV2/Settings/components/Plan/Container.module.css
  10. 226
      src/views/SimproV2/Settings/components/Plan/Container1.js
  11. 356
      src/views/SimproV2/Settings/components/Plan/Container1.module.css
  12. 19
      src/views/SimproV2/Settings/components/SideProfile.js
  13. 44
      src/views/SimproV2/Settings/components/SideProfile.module.css

18
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 = () => {
<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");
@ -25,22 +26,23 @@ const Desktop = () => {
</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"}
>
Account
Plan
</NavLink>
</NavItem>
</Nav>
<TabContent activeTab={activeTab}>
<TabPane tabId="tab1">
<Index1/>
<TabContent activeTab={activeTab} style={{ border:'none' }}>
<TabPane tabId="tab1" style={{ border:'none' }}>
<Index/>
</TabPane>
<TabPane tabId="tab2">
Tab Kedua
<TabPane tabId="tab2" style={{ border:'none' }}>
<Plan/>
</TabPane>
</TabContent>
</section>

71
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 (
<Form>
@ -119,7 +140,7 @@ const DialogForm = ({
</FormGroup>
<FormGroup>
<Label className="capitalize">ID</Label>
<Label className="capitalize">Kode Number</Label>
<Input type="text" value={idNumber || idNumberProp} onChange={(e) => setIdnumber(e.target.value)} />
</FormGroup>
@ -165,11 +186,29 @@ const DialogForm = ({
<Form>
<Row>
<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>
@ -181,12 +220,10 @@ const DialogForm = ({
<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>
<Input type="text" value={newPassword} onChange={(e) => setNewPassword(e.target.value)} />
</FormGroup>
<FormGroup>
<Label className="capitalize">Confirm New Password</Label>
<Input type="text" value={newPasswordConfirm} onChange={(e) => setNewPasswordConfirm(e.target.value)} />
@ -219,6 +256,8 @@ const DialogForm = ({
}
return (
<>
{/* Form */}
<Modal size="lg" isOpen={openDialog} toggle={toggleDialog}>
<ModalHeader className="capitalize" toggle={closeDialog}>
Update {typeDialogProp} {typeDialogProp == 'Refferal' ? ' Code' : ' Data'}
@ -268,6 +307,28 @@ const DialogForm = ({
<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>
</>
)
}

6
src/views/SimproV2/Settings/components/Head.module.css → 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;
}
}

152
src/views/SimproV2/Settings/components/Index1.js → 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}
/>
<div className={stylesHead.head}>
<div className={stylesHead.img}>
<img className={stylesHead.obejct11} alt="" src={profile} />
<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.ibnuHamdani}>
<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.ibnu}>
<div className={stylesHead.content}>
{userProfile && userProfile.username != null ? userProfile.username : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>}
</div>
</div>
</div>
<div className={stylesModule.btnEdit1} style={{ color: '#969696' }} onClick={() => handleOpenDialog('Settings')}>
<div className={stylesModule.icon}>
<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={stylesModule.edit} style={{ fontSize:'16px' }}>Edit</div>
<div className={styles.edit} style={{ fontSize:'16px' }}>Edit</div>
</div>
</div>
<footer className={styles.index1}>
@ -249,7 +323,7 @@ const Index1 = () => {
</div>
<div className={styles.emailParent}>
<div className={styles.email}>Email</div>
<div className={styles.ibnuhamdaniintegrasiautamac}>
<div className={styles.emailContent}>
{userProfile && userProfile.email != null ? userProfile.email : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>}
</div>
</div>
@ -271,7 +345,7 @@ const Index1 = () => {
<div className={styles.row4}>
<div className={styles.column3}>
<div className={styles.name}>Name</div>
<div className={styles.ibnuHamdani}>
<div className={styles.content}>
{userProfile && userProfile.name != null ? userProfile.name : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>}
</div>
</div>
@ -335,8 +409,28 @@ const Index1 = () => {
</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 Index1;
export default Index;

4
src/views/SimproV2/Settings/components/Index1.module.css → 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;
}

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

19
src/views/SimproV2/Settings/components/SideProfile.js

@ -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 (
<header className={styles.sideProfile}>
<div className={styles.side}>
<div className={styles.button1}>
<div className={styles.plan}>My Profile</div>
<div className={styles.plan}>Plan</div>
</div>
</div>
</header>
);
};
export default SideProfile;

44
src/views/SimproV2/Settings/components/SideProfile.module.css

@ -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;
}
}
Loading…
Cancel
Save