farhantock
10 months ago
30 changed files with 3881 additions and 467 deletions
@ -0,0 +1,190 @@ |
|||||||
|
import React, { useEffect, useState } from 'react' |
||||||
|
import { |
||||||
|
Modal, ModalHeader, ModalBody, ModalFooter, |
||||||
|
Button, Form, FormGroup, Label, Input, Col, Row |
||||||
|
} from 'reactstrap'; |
||||||
|
import { Select, DatePicker } from 'antd'; |
||||||
|
import 'antd/dist/antd.css'; |
||||||
|
import { useTranslation } from 'react-i18next'; |
||||||
|
import "rc-color-picker/assets/index.css"; |
||||||
|
import moment from 'moment'; |
||||||
|
import { formatNumber } from "../../../const/CustomFunc"; |
||||||
|
const { Option } = Select |
||||||
|
const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit }) => { |
||||||
|
const [id, setId] = useState(0) |
||||||
|
const [code, setCode] = useState('') |
||||||
|
const [amount, setAmount] = useState(0) |
||||||
|
const [description, setDescription] = useState('') |
||||||
|
const [exp, setExp] = useState('') |
||||||
|
const [type, setType] = useState('') |
||||||
|
const [allocation, setAllocation] = useState(0) |
||||||
|
const { t } = useTranslation() |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
console.log('dataEdit', dataEdit); |
||||||
|
if (typeDialog === "Edit") { |
||||||
|
setId(dataEdit.id) |
||||||
|
setCode(dataEdit.code) |
||||||
|
setAmount(dataEdit.amount) |
||||||
|
setDescription(dataEdit.description) |
||||||
|
setExp(dataEdit.exp) |
||||||
|
setType(dataEdit.type) |
||||||
|
} else { |
||||||
|
handleClear() |
||||||
|
} |
||||||
|
}, [dataEdit, openDialog]) |
||||||
|
|
||||||
|
const validation = () => { |
||||||
|
if (!code || code === "") { |
||||||
|
alert("Code cannot be empty!"); |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
const handleSave = () => { |
||||||
|
let data = ''; |
||||||
|
const err = validation(); |
||||||
|
|
||||||
|
if (!err) { |
||||||
|
if (typeDialog === "Save") { |
||||||
|
data = { |
||||||
|
code, |
||||||
|
amount, |
||||||
|
description, |
||||||
|
exp, |
||||||
|
type, |
||||||
|
allocation |
||||||
|
} |
||||||
|
console.log('data', data); |
||||||
|
closeDialog('save', data); |
||||||
|
} else { |
||||||
|
data = { |
||||||
|
id, |
||||||
|
code, |
||||||
|
amount, |
||||||
|
description, |
||||||
|
exp, |
||||||
|
type, |
||||||
|
allocation |
||||||
|
} |
||||||
|
console.log('data', data); |
||||||
|
closeDialog('edit', data); |
||||||
|
} |
||||||
|
handleClear() |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
const handleCancel = () => { |
||||||
|
closeDialog('cancel', 'none') |
||||||
|
handleClear() |
||||||
|
} |
||||||
|
const handleClear = () => { |
||||||
|
setId(0) |
||||||
|
setCode('') |
||||||
|
setAmount('') |
||||||
|
setDescription('') |
||||||
|
setExp('') |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
const renderForm = () => { |
||||||
|
return ( |
||||||
|
<Form> |
||||||
|
<Row> |
||||||
|
<Col md={12}> |
||||||
|
<span style={{ color: "red" }}>*</span> Wajib diisi. |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<Row> |
||||||
|
<Col md={6}> |
||||||
|
<FormGroup> |
||||||
|
<Label className="capitalize">{t('code')} {t('discount')}<span style={{ color: "red" }}>*</span></Label> |
||||||
|
<Input |
||||||
|
type="text" |
||||||
|
value={code} |
||||||
|
onChange={(e) => setCode(e.target.value)} |
||||||
|
placeholder={t('inputCode')} |
||||||
|
/> |
||||||
|
</FormGroup> |
||||||
|
</Col> |
||||||
|
<Col md={6}> |
||||||
|
<FormGroup> |
||||||
|
<Label className="capitalize">{t('amount')}<span style={{ color: "red" }}>*</span></Label> |
||||||
|
<Input |
||||||
|
type="text" |
||||||
|
value={amount} |
||||||
|
onChange={(e) => setAmount(e.target.value)} |
||||||
|
placeholder={t('inputAmount')} |
||||||
|
/> |
||||||
|
</FormGroup> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<Row> |
||||||
|
<Col md={6}> |
||||||
|
<FormGroup> |
||||||
|
<Label className="capitalize" style={{ fontWeight: "bold" }}> |
||||||
|
{t('exp')}<span style={{ color: "red" }}>*</span> |
||||||
|
</Label> |
||||||
|
<DatePicker |
||||||
|
format={"DD-MM-YYYY HH:mm"} |
||||||
|
style={{ width: "100%" }} |
||||||
|
value={exp ? moment(exp) : exp} |
||||||
|
onChange={(date, dateString) => setExp(date)} |
||||||
|
showTime={{ defaultValue: moment('00:00:00', 'HH:mm:ss') }} |
||||||
|
/> |
||||||
|
|
||||||
|
</FormGroup> |
||||||
|
</Col> |
||||||
|
<Col md={6}> |
||||||
|
<FormGroup> |
||||||
|
<Label className="capitalize">{t('allocation')}<span style={{ color: "red" }}>*</span></Label> |
||||||
|
<Input |
||||||
|
type="number" |
||||||
|
value={allocation} |
||||||
|
onChange={(e) => setAllocation(e.target.value)} |
||||||
|
placeholder={t('input')} |
||||||
|
/> |
||||||
|
</FormGroup> |
||||||
|
</Col> |
||||||
|
<Col md={6}> |
||||||
|
<FormGroup> |
||||||
|
<Label className="capitalize">{t('type')}<span style={{ color: "red" }}>*</span></Label> |
||||||
|
<Input |
||||||
|
type="text" |
||||||
|
value={type} |
||||||
|
onChange={(e) => setType(e.target.value)} |
||||||
|
placeholder={t('inputType')} |
||||||
|
/> |
||||||
|
</FormGroup> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<Row> |
||||||
|
<Col md={12}> |
||||||
|
<FormGroup> |
||||||
|
<Label className="capitalize">{t('description')}</Label> |
||||||
|
<Input row="4" type="textarea" value={description} onChange={(e) => setDescription(e.target.value)} placeholder={t('inputDescription')} /> |
||||||
|
</FormGroup> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Form> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
return ( |
||||||
|
<> |
||||||
|
<Modal size="lg" isOpen={openDialog} toggle={toggleDialog}> |
||||||
|
<ModalHeader className="capitalize" toggle={closeDialog}>{typeDialog == "Save" ? `Add` : "Edit"} {t('Demo')}</ModalHeader> |
||||||
|
<ModalBody> |
||||||
|
{renderForm()} |
||||||
|
</ModalBody> |
||||||
|
<ModalFooter> |
||||||
|
<Button color="primary" onClick={() => handleSave()}>{typeDialog}</Button>{' '} |
||||||
|
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>{t('cancel')}</Button> |
||||||
|
</ModalFooter> |
||||||
|
</Modal> |
||||||
|
</> |
||||||
|
) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
export default DialogForm; |
@ -0,0 +1,372 @@ |
|||||||
|
import * as XLSX from 'xlsx'; |
||||||
|
import DialogForm from './DialogForm'; |
||||||
|
import React, { useState, useEffect } from 'react'; |
||||||
|
import SweetAlert from 'react-bootstrap-sweetalert'; |
||||||
|
import axios from "../../../const/interceptorApi" |
||||||
|
import { Card, CardBody, CardHeader, Col, Row, Input, Table } from 'reactstrap'; |
||||||
|
import { REFERRAL_CODE_EDIT, REFERRAL_CODE_SEARCH, REFERRAL_CODE_ADD, REFERRAL_CODE_DELETE } from '../../../const/ApiConst'; |
||||||
|
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||||
|
import { Spin, Button, Tooltip } from 'antd'; |
||||||
|
import { useTranslation } from 'react-i18next'; |
||||||
|
import moment from 'moment'; |
||||||
|
import toRupiah from '@develoka/angka-rupiah-js'; |
||||||
|
|
||||||
|
const ProjectType = ({ params, ...props }) => { |
||||||
|
let role_id = 0, user_id = 0, isLogin = false, token = '', company_id = 0, all_project = null, role_name = '', hierarchy = [], user_name = ''; |
||||||
|
if (props && props.role_id && props.user_id) { |
||||||
|
role_id = props.role_id; |
||||||
|
user_id = props.user_id; |
||||||
|
token = props.token; |
||||||
|
isLogin = props.isLogin; |
||||||
|
company_id = props.company_id; |
||||||
|
all_project = props.all_project; |
||||||
|
role_name = props.role_name; |
||||||
|
isLogin = props.isLogin; |
||||||
|
hierarchy = props.hierarchy; |
||||||
|
user_name = props.user_name; |
||||||
|
} |
||||||
|
|
||||||
|
const HEADER = { |
||||||
|
headers: { |
||||||
|
"Content-Type": "application/json", |
||||||
|
"Authorization": `Bearer ${token}` |
||||||
|
} |
||||||
|
} |
||||||
|
const pageName = params.name; |
||||||
|
|
||||||
|
const [alertDelete, setAlertDelete] = useState(false) |
||||||
|
const [allDataMenu, setAllDataMenu] = useState([]) |
||||||
|
const [clickOpenModal, setClickOpenModal] = useState(false) |
||||||
|
const [currentPage, setCurrentPage] = useState(1) |
||||||
|
const [dataEdit, setDataEdit] = useState([]) |
||||||
|
const [dataExport, setDataExport] = useState([]) |
||||||
|
const [dataTable, setDatatable] = useState([]) |
||||||
|
const [idDelete, setIdDelete] = useState(0) |
||||||
|
const [openDialog, setOpenDialog] = useState(false) |
||||||
|
const [rowsPerPage, setRowsPerPage] = useState(10) |
||||||
|
const [search, setSearch] = useState("") |
||||||
|
const [totalPage, setTotalPage] = useState(0) |
||||||
|
const [typeDialog, setTypeDialog] = useState('Save') |
||||||
|
const [dataDemo, setDataDemo] = useState([]) |
||||||
|
const [listCompany, setListCompany] = useState([]) |
||||||
|
const [loading, setLoading] = useState(true); |
||||||
|
const { t } = useTranslation() |
||||||
|
const column = [ |
||||||
|
{ name: t('code') }, |
||||||
|
{ name: t('type') }, |
||||||
|
{ name: t('amount') }, |
||||||
|
{ name: t('exp') }, |
||||||
|
{ name: t('allocation') }, |
||||||
|
{ name: t('description') }, |
||||||
|
].filter(column => column && column.name); |
||||||
|
useEffect(() => { |
||||||
|
getReferralCode(); |
||||||
|
}, [currentPage, rowsPerPage, search]) |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
const cekData = dataExport || [] |
||||||
|
if (cekData.length > 0) { |
||||||
|
exportExcel() |
||||||
|
} |
||||||
|
}, [dataExport]) |
||||||
|
|
||||||
|
const getReferralCode = async () => { |
||||||
|
let start = 0; |
||||||
|
if (currentPage !== 1 && currentPage > 1) { |
||||||
|
start = currentPage * rowsPerPage - rowsPerPage; |
||||||
|
} |
||||||
|
const payload = { |
||||||
|
group_column: { |
||||||
|
"operator": "AND", |
||||||
|
"group_operator": "OR", |
||||||
|
"where": [ |
||||||
|
{ |
||||||
|
"name": "name", |
||||||
|
"logic_operator": "~*", |
||||||
|
"value": search, |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
columns: [], |
||||||
|
"orders": { |
||||||
|
"ascending": true, |
||||||
|
"columns": [ |
||||||
|
'id' |
||||||
|
] |
||||||
|
}, |
||||||
|
"paging": { |
||||||
|
"length": rowsPerPage, |
||||||
|
"start": start |
||||||
|
}, |
||||||
|
'joins': [] |
||||||
|
} |
||||||
|
|
||||||
|
const result = await axios |
||||||
|
.post(REFERRAL_CODE_SEARCH, payload, HEADER) |
||||||
|
.then(res => res) |
||||||
|
.catch((error) => error.response); |
||||||
|
|
||||||
|
if (result && result.data && result.data.code == 200) { |
||||||
|
setDatatable(result.data.data); |
||||||
|
setTotalPage(result.data.totalRecord); |
||||||
|
setLoading(false) |
||||||
|
} else { |
||||||
|
NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); |
||||||
|
setLoading(false) |
||||||
|
} |
||||||
|
} |
||||||
|
const handleExportExcel = async () => { |
||||||
|
let start = 0; |
||||||
|
|
||||||
|
if (currentPage !== 1 && currentPage > 1) { |
||||||
|
start = (currentPage * rowsPerPage) - rowsPerPage |
||||||
|
} |
||||||
|
|
||||||
|
const payload = { |
||||||
|
group_column: { |
||||||
|
"operator": "AND", |
||||||
|
"group_operator": "OR", |
||||||
|
"where": [ |
||||||
|
{ |
||||||
|
"name": "name", |
||||||
|
"logic_operator": "~*", |
||||||
|
"value": search, |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
"columns": [], |
||||||
|
"orders": { |
||||||
|
"ascending": true, |
||||||
|
"columns": [ |
||||||
|
'id' |
||||||
|
] |
||||||
|
}, |
||||||
|
"paging": { |
||||||
|
"length": rowsPerPage, |
||||||
|
"start": start |
||||||
|
}, |
||||||
|
'joins': [] |
||||||
|
} |
||||||
|
|
||||||
|
const result = await axios |
||||||
|
.post(REFERRAL_CODE_SEARCH, payload, HEADER) |
||||||
|
.then(res => res) |
||||||
|
.catch((error) => error.response); |
||||||
|
if (result && result.data && result.data.code == 200) { |
||||||
|
let resData = result.data.data; |
||||||
|
const excelData = []; |
||||||
|
resData.map((val, index) => { |
||||||
|
let dataRow = {}; |
||||||
|
dataRow["Kode"] = val.code; |
||||||
|
dataRow["Jumlah"] = val.amount; |
||||||
|
dataRow["Kuota"] = val.allocation; |
||||||
|
dataRow["Kadaluarsa"] = val.exp; |
||||||
|
dataRow["Deskripsi"] = val.deskription; |
||||||
|
excelData.push(dataRow) |
||||||
|
}) |
||||||
|
await setDataExport(excelData) |
||||||
|
} else { |
||||||
|
NotificationManager.error('Gagal Export Data!!', 'Failed'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const exportExcel = () => { |
||||||
|
const dataExcel = dataExport || []; |
||||||
|
const fileName = `Data ${pageName}.xlsx`; |
||||||
|
const ws = XLSX.utils.json_to_sheet(dataExcel); |
||||||
|
const wb = XLSX.utils.book_new(); |
||||||
|
XLSX.utils.book_append_sheet(wb, ws, `Data ${pageName}`); |
||||||
|
XLSX.writeFile(wb, fileName); |
||||||
|
setDataExport([]) |
||||||
|
} |
||||||
|
|
||||||
|
const handleSearch = e => { |
||||||
|
const value = e.target.value |
||||||
|
setSearch(value); |
||||||
|
setCurrentPage(1) |
||||||
|
}; |
||||||
|
|
||||||
|
const handleOpenDialog = (type) => { |
||||||
|
setOpenDialog(true) |
||||||
|
setTypeDialog(type) |
||||||
|
} |
||||||
|
|
||||||
|
const handleEdit = (data) => { |
||||||
|
setDataEdit(data) |
||||||
|
handleOpenDialog('Edit'); |
||||||
|
} |
||||||
|
|
||||||
|
const handleDelete = async (id) => { |
||||||
|
await setAlertDelete(true) |
||||||
|
await setIdDelete(id) |
||||||
|
} |
||||||
|
|
||||||
|
const handleCloseDialog = (type, data) => { |
||||||
|
if (type === "save") { |
||||||
|
saveReferralCode(data); |
||||||
|
} else if (type === "edit") { |
||||||
|
editReferralCode(data); |
||||||
|
} |
||||||
|
setDataEdit([]) |
||||||
|
setOpenDialog(false) |
||||||
|
} |
||||||
|
|
||||||
|
const saveReferralCode = async (data) => { |
||||||
|
const formData = data |
||||||
|
const result = await axios.post(REFERRAL_CODE_ADD, formData, HEADER) |
||||||
|
.then(res => res) |
||||||
|
.catch((error) => error.response); |
||||||
|
if (result && result.data && result.data.code === 200) { |
||||||
|
getReferralCode() |
||||||
|
NotificationManager.success(`Data berhasil ditambahkan`, 'Success!!'); |
||||||
|
} else { |
||||||
|
NotificationManager.error(`Data gagal ditambahkan`, 'Failed!!'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const editReferralCode = async (data) => { |
||||||
|
let urlEdit = REFERRAL_CODE_EDIT(data.id) |
||||||
|
const formData = data |
||||||
|
const result = await axios.put(urlEdit, formData, HEADER) |
||||||
|
.then(res => res) |
||||||
|
.catch((error) => error.response); |
||||||
|
if (result && result.data && result.data.code === 200) { |
||||||
|
getReferralCode(); |
||||||
|
NotificationManager.success(`Data berhasil diubah`, 'Success!!'); |
||||||
|
} else { |
||||||
|
NotificationManager.error(`Data gagal diubah`, `Failed!!`); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const toggleAddDialog = () => { |
||||||
|
setOpenDialog(!openDialog) |
||||||
|
} |
||||||
|
|
||||||
|
const onConfirmDelete = async () => { |
||||||
|
let url = REFERRAL_CODE_DELETE(idDelete); |
||||||
|
const result = await axios.delete(url, HEADER) |
||||||
|
.then(res => res) |
||||||
|
.catch((error) => error.response); |
||||||
|
|
||||||
|
if (result && result.data && result.data.code === 200) { |
||||||
|
getReferralCode() |
||||||
|
setIdDelete(0) |
||||||
|
setAlertDelete(false) |
||||||
|
NotificationManager.success(`Data berhasil dihapus!`, 'Success!!'); |
||||||
|
} else { |
||||||
|
setIdDelete(0) |
||||||
|
setAlertDelete(false) |
||||||
|
NotificationManager.error(`Data gagal dihapus!}`, 'Failed!!'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const cancelDelete = () => { |
||||||
|
setAlertDelete(false) |
||||||
|
setIdDelete(0) |
||||||
|
} |
||||||
|
|
||||||
|
const onShowSizeChange = (current, pageSize) => { |
||||||
|
setRowsPerPage(pageSize) |
||||||
|
} |
||||||
|
|
||||||
|
const onPagination = (current, pageSize) => { |
||||||
|
setCurrentPage(current) |
||||||
|
} |
||||||
|
|
||||||
|
const dataNotAvailable = () => { |
||||||
|
if (dataTable.length === 0) { |
||||||
|
return ( |
||||||
|
<tr> |
||||||
|
<td align="center" colSpan="7">{t('noData')}</td> |
||||||
|
</tr> |
||||||
|
) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<NotificationContainer /> |
||||||
|
<SweetAlert |
||||||
|
show={alertDelete} |
||||||
|
warning |
||||||
|
showCancel |
||||||
|
confirmBtnText="Delete" |
||||||
|
confirmBtnBsStyle="danger" |
||||||
|
title={t('deleteConfirm')} |
||||||
|
onConfirm={onConfirmDelete} |
||||||
|
onCancel={cancelDelete} |
||||||
|
focusCancelBtn |
||||||
|
> |
||||||
|
{t('deleteMsg')} |
||||||
|
</SweetAlert> |
||||||
|
<DialogForm |
||||||
|
openDialog={openDialog} |
||||||
|
closeDialog={handleCloseDialog} |
||||||
|
toggleDialog={() => toggleAddDialog} |
||||||
|
typeDialog={typeDialog} |
||||||
|
dataEdit={dataEdit} |
||||||
|
clickOpenModal={clickOpenModal} |
||||||
|
dataParent={allDataMenu} |
||||||
|
/> |
||||||
|
<Card> |
||||||
|
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
||||||
|
<h4 className="capitalize">{pageName}</h4> |
||||||
|
<Row> |
||||||
|
<Col> |
||||||
|
<Input onChange={handleSearch} value={search} type="text" name="search" id="search" placeholder={t('search')} /> |
||||||
|
</Col> |
||||||
|
<Col> |
||||||
|
<Tooltip title={t('demoAdd')}> |
||||||
|
<Button style={{ background: "#4caf50", color: "#fff" }} onClick={() => handleOpenDialog('Save')}><i className="fa fa-plus"></i></Button> |
||||||
|
</Tooltip> |
||||||
|
<Tooltip title={t('exportExcel')}> |
||||||
|
<Button style={{ marginLeft: "5px" }} onClick={() => handleExportExcel()}><i className="fa fa-print"></i></Button> |
||||||
|
</Tooltip> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</CardHeader> |
||||||
|
<CardBody> |
||||||
|
<Spin tip="Loading..." spinning={loading}> |
||||||
|
<Table responsive striped hover> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th>Aksi</th> |
||||||
|
{column.map((i, index) => { |
||||||
|
return ( |
||||||
|
<th key={index} scope="row">{i.name}</th> |
||||||
|
) |
||||||
|
})} |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
{dataNotAvailable()} |
||||||
|
{dataTable.map((n, index) => { |
||||||
|
return ( |
||||||
|
<tr key={n.id}> |
||||||
|
<td className='nowrap'> |
||||||
|
<Tooltip title={t('delete')}> |
||||||
|
<i id="TooltipDelete" className="fa fa-trash" style={{ color: 'red', marginRight: 10, cursor: "pointer" }} onClick={() => handleDelete(n.id)}></i> |
||||||
|
</Tooltip> |
||||||
|
<Tooltip title={t('edit')}> |
||||||
|
<i id="TooltipEdit" className="fa fa-edit" style={{ color: 'green', cursor: "pointer" }} onClick={() => handleEdit(n)}></i> |
||||||
|
</Tooltip> |
||||||
|
</td> |
||||||
|
<td>{n.code}</td> |
||||||
|
<td>{n.type}</td> |
||||||
|
<td>{toRupiah(n.amount)}</td> |
||||||
|
<td>{n?.exp ? moment(n.exp).format('DD-MM-YYYY HH:mm') : "-"}</td> |
||||||
|
<td>{n.allocation ? n.allocation : "-"}</td> |
||||||
|
<td>{n.description ? n.description : "-"}</td> |
||||||
|
</tr> |
||||||
|
) |
||||||
|
})} |
||||||
|
</tbody> |
||||||
|
</Table> |
||||||
|
</Spin> |
||||||
|
</CardBody> |
||||||
|
</Card> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default ProjectType; |
@ -0,0 +1,201 @@ |
|||||||
|
import React, { useEffect, useState } from 'react' |
||||||
|
import { |
||||||
|
Modal, ModalHeader, ModalBody, ModalFooter, |
||||||
|
Button, Form, FormGroup, Label, Input, Col, Row |
||||||
|
} from 'reactstrap'; |
||||||
|
import { Select } from 'antd'; |
||||||
|
import 'antd/dist/antd.css'; |
||||||
|
import { useTranslation } from 'react-i18next'; |
||||||
|
import "rc-color-picker/assets/index.css"; |
||||||
|
const { Option } = Select |
||||||
|
const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit }) => { |
||||||
|
const [id, setId] = useState(0) |
||||||
|
const [name, setName] = useState('') |
||||||
|
const [email, setEmail] = useState('') |
||||||
|
const [message, setMessage] = useState('') |
||||||
|
const [phoneNumber, setPhoneNumber] = useState('') |
||||||
|
const [role, setRole] = useState(null) |
||||||
|
const [status, setStatus] = useState('') |
||||||
|
const { t } = useTranslation() |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
if (typeDialog === "Edit") { |
||||||
|
setId(dataEdit.id) |
||||||
|
setName(dataEdit.name) |
||||||
|
setEmail(dataEdit.email) |
||||||
|
setMessage(dataEdit.message) |
||||||
|
setPhoneNumber(dataEdit.number_phone) |
||||||
|
setStatus(dataEdit.status) |
||||||
|
setRole(dataEdit.role) |
||||||
|
} else { |
||||||
|
setId(0) |
||||||
|
setName('') |
||||||
|
setEmail('') |
||||||
|
setMessage('') |
||||||
|
setStatus('') |
||||||
|
setRole('') |
||||||
|
setPhoneNumber('') |
||||||
|
} |
||||||
|
}, [dataEdit, openDialog]) |
||||||
|
|
||||||
|
const validation = () => { |
||||||
|
if (!name || name === "") { |
||||||
|
alert("Name cannot be empty!"); |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
const handleSave = () => { |
||||||
|
let data = ''; |
||||||
|
const err = validation(); |
||||||
|
|
||||||
|
if (!err) { |
||||||
|
if (typeDialog === "Save") { |
||||||
|
data = { |
||||||
|
name, |
||||||
|
email, |
||||||
|
message, |
||||||
|
number_phone: phoneNumber, |
||||||
|
role, |
||||||
|
status |
||||||
|
} |
||||||
|
closeDialog('save', data); |
||||||
|
} else { |
||||||
|
data = { |
||||||
|
id, |
||||||
|
name, |
||||||
|
email, |
||||||
|
message, |
||||||
|
number_phone: phoneNumber, |
||||||
|
role, |
||||||
|
status |
||||||
|
} |
||||||
|
closeDialog('edit', data); |
||||||
|
} |
||||||
|
setId(0) |
||||||
|
setName('') |
||||||
|
} |
||||||
|
} |
||||||
|
const handleCancel = () => { |
||||||
|
closeDialog('cancel', 'none') |
||||||
|
setId(0) |
||||||
|
setName('') |
||||||
|
} |
||||||
|
const onChangeStatus = (val) => { |
||||||
|
setStatus(val) |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
const renderForm = () => { |
||||||
|
return ( |
||||||
|
<Form> |
||||||
|
<Row> |
||||||
|
<Col md={12}> |
||||||
|
<span style={{ color: "red" }}>*</span> Wajib diisi. |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<Row> |
||||||
|
<Col md={6}> |
||||||
|
<FormGroup> |
||||||
|
<Label className="capitalize">{t('name')}<span style={{ color: "red" }}>*</span></Label> |
||||||
|
<Input |
||||||
|
type="text" |
||||||
|
value={name} |
||||||
|
onChange={(e) => setName(e.target.value)} |
||||||
|
placeholder={t('inputName')} |
||||||
|
/> |
||||||
|
</FormGroup> |
||||||
|
</Col> |
||||||
|
<Col md={6}> |
||||||
|
<FormGroup> |
||||||
|
<Label className="capitalize">{t('email')}<span style={{ color: "red" }}>*</span></Label> |
||||||
|
<Input |
||||||
|
type="text" |
||||||
|
value={email} |
||||||
|
onChange={(e) => setEmail(e.target.value)} |
||||||
|
placeholder={t('inputEmail')} |
||||||
|
/> |
||||||
|
</FormGroup> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<Row> |
||||||
|
<Col md={6}> |
||||||
|
<FormGroup> |
||||||
|
<Label className="capitalize">{t('phoneNumber')}<span style={{ color: "red" }}>*</span></Label> |
||||||
|
<Input |
||||||
|
type="text" |
||||||
|
value={phoneNumber} |
||||||
|
onChange={(e) => setName(e.target.value)} |
||||||
|
placeholder={t('inputNoPhone')} |
||||||
|
/> |
||||||
|
</FormGroup> |
||||||
|
</Col> |
||||||
|
<Col md={6}> |
||||||
|
<FormGroup> |
||||||
|
<Label className="capitalize">{t('role')}<span style={{ color: "red" }}>*</span></Label> |
||||||
|
<Input |
||||||
|
type="text" |
||||||
|
value={role} |
||||||
|
onChange={(e) => setRole(e.target.value)} |
||||||
|
placeholder={t('inputRole')} |
||||||
|
/> |
||||||
|
</FormGroup> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<Row> |
||||||
|
<Col md={12}> |
||||||
|
<FormGroup> |
||||||
|
<Label className="capitalize"> |
||||||
|
{t('status')}<span style={{ color: "red" }}>*</span> |
||||||
|
</Label> |
||||||
|
<Select |
||||||
|
showSearch |
||||||
|
filterOption={(inputValue, option) => |
||||||
|
option.children.toLowerCase().includes(inputValue.toLowerCase()) |
||||||
|
} |
||||||
|
value={status} |
||||||
|
defaultValue={status} |
||||||
|
onChange={onChangeStatus} |
||||||
|
style={{ width: "100%" }} |
||||||
|
> |
||||||
|
<Option value="New Contact">New Contact</Option> |
||||||
|
<Option value="Presentation">Presentation</Option> |
||||||
|
<Option value="Live Demo">Live Demo</Option> |
||||||
|
<Option value="Trial">Trial</Option> |
||||||
|
<Option value="Go-Live">Go-Live</Option> |
||||||
|
<Option value="Postpone">Postpone</Option> |
||||||
|
|
||||||
|
</Select> |
||||||
|
</FormGroup> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<Row> |
||||||
|
<Col md={12}> |
||||||
|
<FormGroup> |
||||||
|
<Label className="capitalize">{t('message')}</Label> |
||||||
|
<Input row="4" type="textarea" value={message} onChange={(e) => setMessage(e.target.value)} placeholder={t('inputMessage')} /> |
||||||
|
</FormGroup> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Form> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
return ( |
||||||
|
<> |
||||||
|
<Modal size="lg" isOpen={openDialog} toggle={toggleDialog}> |
||||||
|
<ModalHeader className="capitalize" toggle={closeDialog}>{typeDialog == "Save" ? `Add` : "Edit"} {t('Demo')}</ModalHeader> |
||||||
|
<ModalBody> |
||||||
|
{renderForm()} |
||||||
|
</ModalBody> |
||||||
|
<ModalFooter> |
||||||
|
<Button color="primary" onClick={() => handleSave()}>{typeDialog}</Button>{' '} |
||||||
|
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>{t('cancel')}</Button> |
||||||
|
</ModalFooter> |
||||||
|
</Modal> |
||||||
|
</> |
||||||
|
) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
export default DialogForm; |
@ -0,0 +1,374 @@ |
|||||||
|
import * as XLSX from 'xlsx'; |
||||||
|
import DialogForm from './DialogForm'; |
||||||
|
import React, { useState, useEffect } from 'react'; |
||||||
|
import SweetAlert from 'react-bootstrap-sweetalert'; |
||||||
|
import axios from "../../../const/interceptorApi" |
||||||
|
import { Card, CardBody, CardHeader, Col, Row, Input, Table } from 'reactstrap'; |
||||||
|
import { SALES_CONTACT_EDIT, SALES_CONTACT_SEARCH, SALES_CONTACT_LIST, SALES_CONTACT_GET_ID, SALES_CONTACT_ADD, SALES_CONTACT_DELETE } from '../../../const/ApiConst'; |
||||||
|
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||||
|
import { Spin, Button, Tooltip } from 'antd'; |
||||||
|
import { useTranslation } from 'react-i18next'; |
||||||
|
|
||||||
|
|
||||||
|
const ProjectType = ({ params, ...props }) => { |
||||||
|
let role_id = 0, user_id = 0, isLogin = false, token = '', company_id = 0, all_project = null, role_name = '', hierarchy = [], user_name = ''; |
||||||
|
if (props && props.role_id && props.user_id) { |
||||||
|
role_id = props.role_id; |
||||||
|
user_id = props.user_id; |
||||||
|
token = props.token; |
||||||
|
isLogin = props.isLogin; |
||||||
|
company_id = props.company_id; |
||||||
|
all_project = props.all_project; |
||||||
|
role_name = props.role_name; |
||||||
|
isLogin = props.isLogin; |
||||||
|
hierarchy = props.hierarchy; |
||||||
|
user_name = props.user_name; |
||||||
|
} |
||||||
|
|
||||||
|
const HEADER = { |
||||||
|
headers: { |
||||||
|
"Content-Type": "application/json", |
||||||
|
"Authorization": `Bearer ${token}` |
||||||
|
} |
||||||
|
} |
||||||
|
const pageName = params.name; |
||||||
|
|
||||||
|
const [alertDelete, setAlertDelete] = useState(false) |
||||||
|
const [allDataMenu, setAllDataMenu] = useState([]) |
||||||
|
const [clickOpenModal, setClickOpenModal] = useState(false) |
||||||
|
const [currentPage, setCurrentPage] = useState(1) |
||||||
|
const [dataEdit, setDataEdit] = useState([]) |
||||||
|
const [dataExport, setDataExport] = useState([]) |
||||||
|
const [dataTable, setDatatable] = useState([]) |
||||||
|
const [idDelete, setIdDelete] = useState(0) |
||||||
|
const [openDialog, setOpenDialog] = useState(false) |
||||||
|
const [rowsPerPage, setRowsPerPage] = useState(10) |
||||||
|
const [search, setSearch] = useState("") |
||||||
|
const [totalPage, setTotalPage] = useState(0) |
||||||
|
const [typeDialog, setTypeDialog] = useState('Save') |
||||||
|
const [dataDemo, setDataDemo] = useState([]) |
||||||
|
const [listCompany, setListCompany] = useState([]) |
||||||
|
const [loading, setLoading] = useState(true); |
||||||
|
const { t } = useTranslation() |
||||||
|
const column = [ |
||||||
|
{ name: t('name') }, |
||||||
|
{ name: t('company') }, |
||||||
|
{ name: t('email') }, |
||||||
|
{ name: t('roles') }, |
||||||
|
{ name: t('phoneNumber') }, |
||||||
|
{ name: t('status') }, |
||||||
|
{ name: t('description') }, |
||||||
|
].filter(column => column && column.name); |
||||||
|
useEffect(() => { |
||||||
|
getDataContactSales(); |
||||||
|
}, [currentPage, rowsPerPage, search]) |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
const cekData = dataExport || [] |
||||||
|
if (cekData.length > 0) { |
||||||
|
exportExcel() |
||||||
|
} |
||||||
|
}, [dataExport]) |
||||||
|
|
||||||
|
const getDataContactSales = async () => { |
||||||
|
let start = 0; |
||||||
|
if (currentPage !== 1 && currentPage > 1) { |
||||||
|
start = currentPage * rowsPerPage - rowsPerPage; |
||||||
|
} |
||||||
|
const payload = { |
||||||
|
group_column: { |
||||||
|
"operator": "AND", |
||||||
|
"group_operator": "OR", |
||||||
|
"where": [ |
||||||
|
{ |
||||||
|
"name": "name", |
||||||
|
"logic_operator": "~*", |
||||||
|
"value": search, |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
columns: [], |
||||||
|
"orders": { |
||||||
|
"ascending": true, |
||||||
|
"columns": [ |
||||||
|
'id' |
||||||
|
] |
||||||
|
}, |
||||||
|
"paging": { |
||||||
|
"length": rowsPerPage, |
||||||
|
"start": start |
||||||
|
}, |
||||||
|
'joins': [] |
||||||
|
} |
||||||
|
|
||||||
|
const result = await axios |
||||||
|
.post(SALES_CONTACT_SEARCH, payload, HEADER) |
||||||
|
.then(res => res) |
||||||
|
.catch((error) => error.response); |
||||||
|
|
||||||
|
if (result && result.data && result.data.code == 200) { |
||||||
|
setDatatable(result.data.data); |
||||||
|
setTotalPage(result.data.totalRecord); |
||||||
|
setLoading(false) |
||||||
|
} else { |
||||||
|
NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); |
||||||
|
setLoading(false) |
||||||
|
} |
||||||
|
} |
||||||
|
const handleExportExcel = async () => { |
||||||
|
let start = 0; |
||||||
|
|
||||||
|
if (currentPage !== 1 && currentPage > 1) { |
||||||
|
start = (currentPage * rowsPerPage) - rowsPerPage |
||||||
|
} |
||||||
|
|
||||||
|
const payload = { |
||||||
|
group_column: { |
||||||
|
"operator": "AND", |
||||||
|
"group_operator": "OR", |
||||||
|
"where": [ |
||||||
|
{ |
||||||
|
"name": "name", |
||||||
|
"logic_operator": "~*", |
||||||
|
"value": search, |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
"columns": [], |
||||||
|
"orders": { |
||||||
|
"ascending": true, |
||||||
|
"columns": [ |
||||||
|
'id' |
||||||
|
] |
||||||
|
}, |
||||||
|
"paging": { |
||||||
|
"length": rowsPerPage, |
||||||
|
"start": start |
||||||
|
}, |
||||||
|
'joins': [] |
||||||
|
} |
||||||
|
|
||||||
|
const result = await axios |
||||||
|
.post(SALES_CONTACT_SEARCH, payload, HEADER) |
||||||
|
.then(res => res) |
||||||
|
.catch((error) => error.response); |
||||||
|
if (result && result.data && result.data.code == 200) { |
||||||
|
let resData = result.data.data; |
||||||
|
const excelData = []; |
||||||
|
resData.map((val, index) => { |
||||||
|
let dataRow = {}; |
||||||
|
dataRow["Nama"] = val.name; |
||||||
|
dataRow["Email"] = val.email; |
||||||
|
dataRow["Role"] = val.role; |
||||||
|
dataRow["No Telepon"] = val.number_phone; |
||||||
|
dataRow["Status"] = val.message; |
||||||
|
dataRow["Message"] = val.message; |
||||||
|
excelData.push(dataRow) |
||||||
|
}) |
||||||
|
await setDataExport(excelData) |
||||||
|
} else { |
||||||
|
NotificationManager.error('Gagal Export Data!!', 'Failed'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const exportExcel = () => { |
||||||
|
const dataExcel = dataExport || []; |
||||||
|
const fileName = `Data ${pageName}.xlsx`; |
||||||
|
const ws = XLSX.utils.json_to_sheet(dataExcel); |
||||||
|
const wb = XLSX.utils.book_new(); |
||||||
|
XLSX.utils.book_append_sheet(wb, ws, `Data ${pageName}`); |
||||||
|
XLSX.writeFile(wb, fileName); |
||||||
|
setDataExport([]) |
||||||
|
} |
||||||
|
|
||||||
|
const handleSearch = e => { |
||||||
|
const value = e.target.value |
||||||
|
setSearch(value); |
||||||
|
setCurrentPage(1) |
||||||
|
}; |
||||||
|
|
||||||
|
const handleOpenDialog = (type) => { |
||||||
|
setOpenDialog(true) |
||||||
|
setTypeDialog(type) |
||||||
|
} |
||||||
|
|
||||||
|
const handleEdit = (data) => { |
||||||
|
setDataEdit(data) |
||||||
|
handleOpenDialog('Edit'); |
||||||
|
} |
||||||
|
|
||||||
|
const handleDelete = async (id) => { |
||||||
|
await setAlertDelete(true) |
||||||
|
await setIdDelete(id) |
||||||
|
} |
||||||
|
|
||||||
|
const handleCloseDialog = (type, data) => { |
||||||
|
if (type === "save") { |
||||||
|
saveContactSales(data); |
||||||
|
} else if (type === "edit") { |
||||||
|
editContactSales(data); |
||||||
|
} |
||||||
|
setDataEdit([]) |
||||||
|
setOpenDialog(false) |
||||||
|
} |
||||||
|
|
||||||
|
const saveContactSales = async (data) => { |
||||||
|
const formData = data |
||||||
|
const result = await axios.post(SALES_CONTACT_ADD, formData, HEADER) |
||||||
|
.then(res => res) |
||||||
|
.catch((error) => error.response); |
||||||
|
if (result && result.data && result.data.code === 200) { |
||||||
|
getDataContactSales() |
||||||
|
NotificationManager.success(`Data berhasil ditambahkan`, 'Success!!'); |
||||||
|
} else { |
||||||
|
NotificationManager.error(`Data gagal ditambahkan`, 'Failed!!'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const editContactSales = async (data) => { |
||||||
|
let urlEdit = SALES_CONTACT_EDIT(data.id) |
||||||
|
const formData = data |
||||||
|
const result = await axios.put(urlEdit, formData, HEADER) |
||||||
|
.then(res => res) |
||||||
|
.catch((error) => error.response); |
||||||
|
if (result && result.data && result.data.code === 200) { |
||||||
|
getDataContactSales(); |
||||||
|
NotificationManager.success(`Data berhasil diubah`, 'Success!!'); |
||||||
|
} else { |
||||||
|
NotificationManager.error(`Data gagal diubah`, `Failed!!`); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const toggleAddDialog = () => { |
||||||
|
setOpenDialog(!openDialog) |
||||||
|
} |
||||||
|
|
||||||
|
const onConfirmDelete = async () => { |
||||||
|
let url = SALES_CONTACT_DELETE(idDelete); |
||||||
|
const result = await axios.delete(url, HEADER) |
||||||
|
.then(res => res) |
||||||
|
.catch((error) => error.response); |
||||||
|
|
||||||
|
if (result && result.data && result.data.code === 200) { |
||||||
|
getDataContactSales() |
||||||
|
setIdDelete(0) |
||||||
|
setAlertDelete(false) |
||||||
|
NotificationManager.success(`Data berhasil dihapus!`, 'Success!!'); |
||||||
|
} else { |
||||||
|
setIdDelete(0) |
||||||
|
setAlertDelete(false) |
||||||
|
NotificationManager.error(`Data gagal dihapus!}`, 'Failed!!'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const cancelDelete = () => { |
||||||
|
setAlertDelete(false) |
||||||
|
setIdDelete(0) |
||||||
|
} |
||||||
|
|
||||||
|
const onShowSizeChange = (current, pageSize) => { |
||||||
|
setRowsPerPage(pageSize) |
||||||
|
} |
||||||
|
|
||||||
|
const onPagination = (current, pageSize) => { |
||||||
|
setCurrentPage(current) |
||||||
|
} |
||||||
|
|
||||||
|
const dataNotAvailable = () => { |
||||||
|
if (dataTable.length === 0) { |
||||||
|
return ( |
||||||
|
<tr> |
||||||
|
<td align="center" colSpan="8">{t('noData')}</td> |
||||||
|
</tr> |
||||||
|
) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<NotificationContainer /> |
||||||
|
<SweetAlert |
||||||
|
show={alertDelete} |
||||||
|
warning |
||||||
|
showCancel |
||||||
|
confirmBtnText="Delete" |
||||||
|
confirmBtnBsStyle="danger" |
||||||
|
title={t('deleteConfirm')} |
||||||
|
onConfirm={onConfirmDelete} |
||||||
|
onCancel={cancelDelete} |
||||||
|
focusCancelBtn |
||||||
|
> |
||||||
|
{t('deleteMsg')} |
||||||
|
</SweetAlert> |
||||||
|
<DialogForm |
||||||
|
openDialog={openDialog} |
||||||
|
closeDialog={handleCloseDialog} |
||||||
|
toggleDialog={() => toggleAddDialog} |
||||||
|
typeDialog={typeDialog} |
||||||
|
dataEdit={dataEdit} |
||||||
|
clickOpenModal={clickOpenModal} |
||||||
|
dataParent={allDataMenu} |
||||||
|
/> |
||||||
|
<Card> |
||||||
|
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
||||||
|
<h4 className="capitalize">{pageName}</h4> |
||||||
|
<Row> |
||||||
|
<Col> |
||||||
|
<Input onChange={handleSearch} value={search} type="text" name="search" id="search" placeholder={t('searchDemo')} /> |
||||||
|
</Col> |
||||||
|
<Col> |
||||||
|
<Tooltip title={t('demoAdd')}> |
||||||
|
<Button style={{ background: "#4caf50", color: "#fff" }} onClick={() => handleOpenDialog('Save')}><i className="fa fa-plus"></i></Button> |
||||||
|
</Tooltip> |
||||||
|
<Tooltip title={t('exportExcel')}> |
||||||
|
<Button style={{ marginLeft: "5px" }} onClick={() => handleExportExcel()}><i className="fa fa-print"></i></Button> |
||||||
|
</Tooltip> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</CardHeader> |
||||||
|
<CardBody> |
||||||
|
<Spin tip="Loading..." spinning={loading}> |
||||||
|
<Table responsive striped hover> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th>Aksi</th> |
||||||
|
{column.map((i, index) => { |
||||||
|
return ( |
||||||
|
<th key={index} scope="row">{i.name}</th> |
||||||
|
) |
||||||
|
})} |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
{dataNotAvailable()} |
||||||
|
{dataTable.map((n, index) => { |
||||||
|
return ( |
||||||
|
<tr key={n.id}> |
||||||
|
<td className='nowrap'> |
||||||
|
<Tooltip title={t('delete')}> |
||||||
|
<i id="TooltipDelete" className="fa fa-trash" style={{ color: 'red', marginRight: 10, cursor: "pointer" }} onClick={() => handleDelete(n.id)}></i> |
||||||
|
</Tooltip> |
||||||
|
<Tooltip title={t('edit')}> |
||||||
|
<i id="TooltipEdit" className="fa fa-edit" style={{ color: 'green', cursor: "pointer" }} onClick={() => handleEdit(n)}></i> |
||||||
|
</Tooltip> |
||||||
|
</td> |
||||||
|
<td>{n.name}</td> |
||||||
|
<td>{n.company_name}</td> |
||||||
|
<td>{n.email}</td> |
||||||
|
<td>{n.role}</td> |
||||||
|
<td>{n.number_phone}</td> |
||||||
|
<td>{n.status}</td> |
||||||
|
<td>{n.message}</td> |
||||||
|
</tr> |
||||||
|
) |
||||||
|
})} |
||||||
|
</tbody> |
||||||
|
</Table> |
||||||
|
</Spin> |
||||||
|
</CardBody> |
||||||
|
</Card> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default ProjectType; |
@ -0,0 +1,53 @@ |
|||||||
|
import Index from "./components/MyProfile/Index"; |
||||||
|
import styles from "./Desktop.module.css"; |
||||||
|
import Plan from "./components/Plan/Container1"; |
||||||
|
import React, { useState, useEffect } from 'react'; |
||||||
|
import { Nav, NavItem, NavLink, TabContent, TabPane } from 'reactstrap'; |
||||||
|
|
||||||
|
const Desktop = () => { |
||||||
|
const [activeTab, setActiveTab] = useState('tab1') |
||||||
|
const [typeTab, setTypeTab] = useState('myprofile') |
||||||
|
|
||||||
|
return ( |
||||||
|
<main className={styles.myProfile}> |
||||||
|
<section className={styles.profile}> |
||||||
|
<Nav tabs> |
||||||
|
<NavItem> |
||||||
|
<NavLink |
||||||
|
style={{ borderRadius: typeTab === 'myprofile' ? '15px' : '', backgroundColor: typeTab === 'myprofile' ? '#E0ECF5' : '', color: typeTab === 'myprofile' ? '#48A4F0' : '', fontWeight:'600', border:'none' }} |
||||||
|
onClick={() => { |
||||||
|
setActiveTab("tab1"); |
||||||
|
setTypeTab("myprofile"); |
||||||
|
}} |
||||||
|
active={activeTab === "tab1"} |
||||||
|
> |
||||||
|
My Profile |
||||||
|
</NavLink> |
||||||
|
</NavItem> |
||||||
|
<NavItem> |
||||||
|
<NavLink |
||||||
|
style={{ borderRadius: typeTab === 'plan' ? '15px' : '', backgroundColor: typeTab === 'plan' ? '#E0ECF5' : '', color: typeTab === 'plan' ? '#48A4F0' : '', fontWeight:'600', border:'none' }} |
||||||
|
onClick={() => { |
||||||
|
setActiveTab("tab2"); |
||||||
|
setTypeTab("plan"); |
||||||
|
}} |
||||||
|
active={activeTab === "tab2"} |
||||||
|
> |
||||||
|
Plan |
||||||
|
</NavLink> |
||||||
|
</NavItem> |
||||||
|
</Nav> |
||||||
|
<TabContent activeTab={activeTab} style={{ border:'none' }}> |
||||||
|
<TabPane tabId="tab1" style={{ border:'none' }}> |
||||||
|
<Index/> |
||||||
|
</TabPane> |
||||||
|
<TabPane tabId="tab2" style={{ border:'none' }}> |
||||||
|
<Plan/> |
||||||
|
</TabPane> |
||||||
|
</TabContent> |
||||||
|
</section> |
||||||
|
</main> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
export default Desktop; |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,69 @@ |
|||||||
|
.obejct11 { |
||||||
|
width: 55px; |
||||||
|
height: 54px; |
||||||
|
position: relative; |
||||||
|
border-radius: 79.5px; |
||||||
|
object-fit: cover; |
||||||
|
} |
||||||
|
.img { |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
align-items: center; |
||||||
|
justify-content: flex-start; |
||||||
|
padding: 20px 0; |
||||||
|
} |
||||||
|
.headContent { |
||||||
|
position: relative; |
||||||
|
font-weight: 600; |
||||||
|
} |
||||||
|
.headTitle { |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
align-items: flex-start; |
||||||
|
justify-content: center; |
||||||
|
} |
||||||
|
.content { |
||||||
|
position: relative; |
||||||
|
font-weight: 600; |
||||||
|
} |
||||||
|
.headSubtitle { |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
align-items: flex-start; |
||||||
|
justify-content: center; |
||||||
|
font-size: 16px; |
||||||
|
color: #777; |
||||||
|
} |
||||||
|
.head, |
||||||
|
.text { |
||||||
|
box-sizing: border-box; |
||||||
|
display: flex; |
||||||
|
} |
||||||
|
.text { |
||||||
|
width: 1032px; |
||||||
|
flex-direction: column; |
||||||
|
align-items: flex-start; |
||||||
|
justify-content: center; |
||||||
|
padding: 20px 0; |
||||||
|
gap: 5px 0; |
||||||
|
} |
||||||
|
.head { |
||||||
|
align-self: stretch; |
||||||
|
height: 98px; |
||||||
|
background-color: #fff; |
||||||
|
border: 1px solid #7eacd3; |
||||||
|
flex-shrink: 0; |
||||||
|
flex-direction: row; |
||||||
|
align-items: center; |
||||||
|
justify-content: flex-start; |
||||||
|
padding: 0 16px 0 14px; |
||||||
|
gap: 0 20px; |
||||||
|
text-align: left; |
||||||
|
font-size: 20px; |
||||||
|
color: #333; |
||||||
|
} |
||||||
|
@media screen and (max-width: 450px) { |
||||||
|
.headContent { |
||||||
|
font-size: 16px; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,436 @@ |
|||||||
|
import * as XLSX from 'xlsx'; |
||||||
|
import React, { useState, useEffect, useMemo } from 'react'; |
||||||
|
import axios from "../../../../../const/interceptorApi" |
||||||
|
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||||
|
import { Pagination, Tooltip } from 'antd'; |
||||||
|
import { USER_EDIT, REFFERAL_ADD, REFFERAL_EDIT, ROLE_SEARCH, USER_SEARCH, IMAGE_UPLOAD, IMAGE_DELETE, IMAGE_GET_BY_ID, BASE_SIMPRO_LUMEN_IMAGE_COMPANY } from '../../../../../const/ApiConst'; |
||||||
|
import DialogForm from '../../DialogForm' |
||||||
|
import styles from "./Index.module.css"; |
||||||
|
import profile from '../../../../../assets/img/profile.png' |
||||||
|
import stylesHead from "./Head.module.css"; |
||||||
|
import moment from 'moment'; |
||||||
|
import { Modal, ModalBody, ModalFooter, Button } from 'reactstrap'; |
||||||
|
|
||||||
|
const Index = () => { |
||||||
|
const token = localStorage.getItem("token") |
||||||
|
const user_id = localStorage.getItem("user_id") |
||||||
|
let company_id = '', configApp = ''; |
||||||
|
const role = window.localStorage.getItem('role_name'); |
||||||
|
if(role !== 'Super Admin') { |
||||||
|
company_id = localStorage.getItem("company_id"); |
||||||
|
configApp = JSON.parse(window.localStorage.getItem('configApp')); |
||||||
|
} |
||||||
|
const config = { |
||||||
|
headers: { |
||||||
|
"Content-Type": "application/json", |
||||||
|
"Authorization": `Bearer ${token}` |
||||||
|
} |
||||||
|
} |
||||||
|
const HEADER_MULTIPART = { |
||||||
|
headers: { |
||||||
|
"Content-Type": "multipart/form-data", |
||||||
|
Authorization: `Bearer ${token}`, |
||||||
|
}, |
||||||
|
}; |
||||||
|
const [openDialog, setOpenDialog] = useState(false) |
||||||
|
const [typeDialog, setTypeDialog] = useState('') |
||||||
|
const [roleList, setRoleList] = useState([]) |
||||||
|
const [refferal, setReferralCode] = useState(null) |
||||||
|
const [isCopied, setIsCopied] = useState(false) |
||||||
|
const [userProfile, setUserprofile] = useState(null) |
||||||
|
const [imageProfile, setImageProfile] = useState(null); |
||||||
|
const [modalOpen, setModalOpen] = useState(false) |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
getImageProfle(parseInt(user_id)); |
||||||
|
getRoleList(); |
||||||
|
getDataProfileUser(); |
||||||
|
}, []) |
||||||
|
|
||||||
|
const getDataProfileUser = async () => { |
||||||
|
const formData = { |
||||||
|
"paging": {"start": 0, "length": 1}, |
||||||
|
"columns": [ |
||||||
|
{"name": "id", "logic_operator": "=", "value": parseInt(user_id), "operator": "AND"} |
||||||
|
], |
||||||
|
"joins": [ |
||||||
|
{ |
||||||
|
"name": "m_divisi", |
||||||
|
"column_join": "divisi_id", |
||||||
|
"column_results": [ |
||||||
|
"name" |
||||||
|
] |
||||||
|
}, |
||||||
|
{ |
||||||
|
"name": "refferal_code", |
||||||
|
"column_join": "discount_id", |
||||||
|
"column_results": [ |
||||||
|
"code" |
||||||
|
] |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
const result = await axios |
||||||
|
.post(USER_SEARCH, formData, config) |
||||||
|
.then(res => res) |
||||||
|
.catch((error) => error.response ); |
||||||
|
if (result && result.data && result.data.code == 200) { |
||||||
|
let dataRes = result.data.data[0]; |
||||||
|
setUserprofile(dataRes); |
||||||
|
if(!dataRes.discount_id || dataRes.discount_id === null || dataRes.discount_id === '') { |
||||||
|
saveRefferalCode(dataRes?.username, dataRes?.ktp_number); |
||||||
|
} else { |
||||||
|
setReferralCode(dataRes.join_second_code); |
||||||
|
} |
||||||
|
} else { |
||||||
|
NotificationManager.error("Gagal Mengambil Data!!", "Failed"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const handleOpenDialog = (type) => { |
||||||
|
setOpenDialog(true) |
||||||
|
setTypeDialog(type) |
||||||
|
} |
||||||
|
|
||||||
|
const handleCloseDialog = (type, data) => { |
||||||
|
if (type === "profile") { |
||||||
|
saveProfile(data); |
||||||
|
} else if(type === "refferal_code") { |
||||||
|
updateRefferal(data); |
||||||
|
} |
||||||
|
setOpenDialog(false) |
||||||
|
} |
||||||
|
|
||||||
|
const saveProfile = async (data) => { |
||||||
|
let urlEdit = USER_EDIT(user_id) |
||||||
|
const formData = data |
||||||
|
const result = await axios.put(urlEdit, formData, config) |
||||||
|
.then(res => res) |
||||||
|
.catch((error) => error.response); |
||||||
|
if (result && result.data && result.data.code === 200) { |
||||||
|
const profilePicture = data.profilePicture; |
||||||
|
if (profilePicture && profilePicture != null) { |
||||||
|
await deleteImageProfile( |
||||||
|
parseInt(user_id), |
||||||
|
); |
||||||
|
await saveImageProfile( |
||||||
|
parseInt(user_id), |
||||||
|
profilePicture |
||||||
|
); |
||||||
|
} |
||||||
|
getDataProfileUser() |
||||||
|
getImageProfle(user_id) |
||||||
|
NotificationManager.success(`Data profile berhasil diedit`, 'Success!!'); |
||||||
|
} else { |
||||||
|
NotificationManager.error(`Data profile gagal di edit`, `Failed!!`); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Save Image Function
|
||||||
|
const saveImageProfile = async (id, data) => { |
||||||
|
const formData = new FormData; |
||||||
|
formData.append('ref_id', id); |
||||||
|
formData.append('category', 'profile_picture'); |
||||||
|
formData.append('files', data); |
||||||
|
if(role !== 'Super Admin') { |
||||||
|
formData.append('company_name', configApp.company_name); |
||||||
|
} |
||||||
|
await axios |
||||||
|
.post(IMAGE_UPLOAD, formData, HEADER_MULTIPART) |
||||||
|
.then(res => res) |
||||||
|
.catch((error) => error.response); |
||||||
|
}; |
||||||
|
|
||||||
|
// Delete Image Function
|
||||||
|
const deleteImageProfile = async (id) => { |
||||||
|
const URL = IMAGE_DELETE(id, 'profile_picture', company_id != '' ? company_id : 'undifined'); |
||||||
|
await axios |
||||||
|
.delete(URL, config) |
||||||
|
.then(res => res) |
||||||
|
.catch((error) => error.response); |
||||||
|
}; |
||||||
|
|
||||||
|
const getImageProfle = async (id) => { |
||||||
|
const url = IMAGE_GET_BY_ID(id, "profile_picture"); |
||||||
|
const result = await axios |
||||||
|
.get(url, config) |
||||||
|
.then((res) => res) |
||||||
|
.catch((err) => err.response); |
||||||
|
if (result && result.data && result.data.code === 200) { |
||||||
|
setImageProfile(result.data.data); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const updateRefferal = async (data) => { |
||||||
|
let urlEdit = REFFERAL_EDIT(userProfile?.id) |
||||||
|
const formData = data |
||||||
|
const result = await axios.put(urlEdit, formData, config) |
||||||
|
.then(res => res) |
||||||
|
.catch((error) => error.response); |
||||||
|
if (result && result.data && result.data.code === 200) { |
||||||
|
getDataProfileUser(data.user_id, data.username, data.ktp_number); |
||||||
|
NotificationManager.success(`Code refferal berhasil diedit`, 'Success!!'); |
||||||
|
} else { |
||||||
|
NotificationManager.error(`Code refferal gagal di edit`, `Failed!!`); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const toggleAddDialog = () => { |
||||||
|
setOpenDialog(!openDialog) |
||||||
|
} |
||||||
|
|
||||||
|
const toggleModal = () => { |
||||||
|
setModalOpen(!modalOpen); |
||||||
|
}; |
||||||
|
|
||||||
|
const handleImageClick = async () => { |
||||||
|
toggleModal(); |
||||||
|
}; |
||||||
|
|
||||||
|
const getRoleList = async () => { |
||||||
|
const formData = { |
||||||
|
"paging": { "start": 0, "length": -1 }, |
||||||
|
"orders": { "columns": ["id"], "ascending": false } |
||||||
|
} |
||||||
|
const result = await axios |
||||||
|
.post(ROLE_SEARCH, formData, config) |
||||||
|
.then(res => res) |
||||||
|
.catch((error) => error.response); |
||||||
|
if (result && result.data && result.data.code == 200) { |
||||||
|
setRoleList(result.data.data); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const saveRefferalCode = async (username, ktp_number) => { |
||||||
|
const formData = { |
||||||
|
'code': username + ktp_number.substring(0, 4), |
||||||
|
'amount': 0 |
||||||
|
} |
||||||
|
const result = await axios |
||||||
|
.post(REFFERAL_ADD, formData, config) |
||||||
|
.then((res) => res) |
||||||
|
.catch((error) => error.response); |
||||||
|
if (result && result.data && result.data.code == 200) { |
||||||
|
const data = {'discount_id': result.data.data.id}; |
||||||
|
await saveProfile(data); |
||||||
|
} else { |
||||||
|
NotificationManager.error('Kode refferal gagal ditambahkan!!', 'Failed'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function copyToClipboard(text) { |
||||||
|
navigator.clipboard.writeText(text).then(() => { |
||||||
|
setIsCopied(true); |
||||||
|
setTimeout(() => setIsCopied(false), 2000); |
||||||
|
}, (err) => { |
||||||
|
console.error('Gagal menyalin teks ke clipboard: ', err); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<> |
||||||
|
<NotificationContainer /> |
||||||
|
<DialogForm |
||||||
|
openDialog={openDialog} |
||||||
|
closeDialog={handleCloseDialog} |
||||||
|
toggleDialog={() => toggleAddDialog} |
||||||
|
typeDialogProp={typeDialog} |
||||||
|
roleList={roleList} |
||||||
|
nameProp={userProfile?.name} |
||||||
|
noHpProp={userProfile?.phone_number} |
||||||
|
idNumberProp={userProfile?.ktp_number} |
||||||
|
genderProp={userProfile?.gender} |
||||||
|
divisiProp={userProfile?.join_first_name} |
||||||
|
birthdayPlaceProp={userProfile?.birth_place} |
||||||
|
birthdayDateProp={userProfile?.birth_date} |
||||||
|
addressProp={userProfile?.address} |
||||||
|
emailProp={userProfile?.email} |
||||||
|
userNameProp={userProfile?.username} |
||||||
|
refferalCode={refferal} |
||||||
|
userProfile={userProfile} |
||||||
|
imageProfile={imageProfile} |
||||||
|
/> |
||||||
|
<div className={stylesHead.head}> |
||||||
|
<div className={stylesHead.img} style={{ cursor:imageProfile ? 'pointer' : '' }} onClick={imageProfile ? () => handleImageClick() : ''}> |
||||||
|
<img className={stylesHead.obejct11} src={ |
||||||
|
imageProfile ? ( |
||||||
|
`${BASE_SIMPRO_LUMEN_IMAGE_COMPANY(imageProfile?.image, role != 'Super Admin' ? configApp.company_name : 'undifined')}` |
||||||
|
) : profile |
||||||
|
} /> |
||||||
|
</div> |
||||||
|
<div className={stylesHead.text}> |
||||||
|
<div className={stylesHead.headTitle}> |
||||||
|
<div className={stylesHead.headContent}> |
||||||
|
{userProfile && userProfile.name != null ? userProfile.name : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div className={stylesHead.headSubtitle}> |
||||||
|
<div className={stylesHead.content}> |
||||||
|
{userProfile && userProfile.username != null ? userProfile.username : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div className={styles.btnEdit1} style={{ color: '#969696' }} onClick={() => handleOpenDialog('Settings')}> |
||||||
|
<div className={styles.icon}> |
||||||
|
<i className="fa fa-edit" style={{ fontSize:'16px' }}></i> |
||||||
|
</div> |
||||||
|
<div className={styles.edit} style={{ fontSize:'16px' }}>Edit</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<footer className={styles.index1}> |
||||||
|
<div className={styles.row}> |
||||||
|
<div className={styles.column}> |
||||||
|
<div className={styles.text}> |
||||||
|
<div className={styles.headTitle}> |
||||||
|
<div className={styles.codeReferal}>Refferal Code</div> |
||||||
|
</div> |
||||||
|
<div className={styles.headSubtitle}> |
||||||
|
<div className={styles.ibnu212} style={{ color:'#20A8D8' }}>{refferal ? refferal : 'empty'}</div> |
||||||
|
<Tooltip title= {!isCopied ? "Copy Refferal" : "Copied"}> |
||||||
|
<span onClick={() => copyToClipboard(refferal ? refferal : 'empty')}> |
||||||
|
{isCopied ? |
||||||
|
<i className="fa fa-check" style={{ cursor:'pointer' }}></i> |
||||||
|
: |
||||||
|
<i className="fa fa-clipboard" style={{ cursor:'pointer' }}></i>} |
||||||
|
</span> |
||||||
|
</Tooltip> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div className={styles.btnEdit1} onClick={() => handleOpenDialog('Refferal')}> |
||||||
|
<div className={styles.icon}> |
||||||
|
<i className="fa fa-edit"></i> |
||||||
|
</div> |
||||||
|
<div className={styles.edit}>Edit</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div className={styles.row1}> |
||||||
|
<div className={styles.column1}> |
||||||
|
<div className={styles.accountInformation}>Account Information</div> |
||||||
|
<div className={styles.btnEdit2} onClick={() => handleOpenDialog('Account')}> |
||||||
|
<div className={styles.icon1}> |
||||||
|
<i className="fa fa-edit"></i> |
||||||
|
</div> |
||||||
|
<div className={styles.edit1}>Edit</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div className={styles.column2}> |
||||||
|
<div className={styles.frameParent}> |
||||||
|
<div className={styles.usernameParent}> |
||||||
|
<div className={styles.username}>Username</div> |
||||||
|
<div className={styles.ibnu}> |
||||||
|
{userProfile && userProfile.username != null ? userProfile.username : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div className={styles.emailParent}> |
||||||
|
<div className={styles.email}>Email</div> |
||||||
|
<div className={styles.emailContent}> |
||||||
|
{userProfile && userProfile.email != null ? userProfile.email : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div className={styles.row2}> |
||||||
|
<div className={styles.row3}> |
||||||
|
<div className={styles.personalInformation}>Personal Information</div> |
||||||
|
<div className={styles.btnEdit3} onClick={() => handleOpenDialog('Personal')}> |
||||||
|
<div className={styles.icon3}> |
||||||
|
<i className="fa fa-edit"></i> |
||||||
|
</div> |
||||||
|
<div className={styles.edit2}>Edit</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div className={styles.div}> |
||||||
|
<div className={styles.row4}> |
||||||
|
<div className={styles.column3}> |
||||||
|
<div className={styles.name}>Name</div> |
||||||
|
<div className={styles.content}> |
||||||
|
{userProfile && userProfile.name != null ? userProfile.name : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div className={styles.column4}> |
||||||
|
<div className={styles.noHp}>Telephone</div> |
||||||
|
<div className={styles.birthDetailsColumn}> |
||||||
|
{userProfile && userProfile.phone_number != null ? userProfile.phone_number : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div className={styles.row5}> |
||||||
|
<div className={styles.column5}> |
||||||
|
<div className={styles.idNumber}>Kode Number</div> |
||||||
|
<div className={styles.div1}> |
||||||
|
{userProfile && userProfile.ktp_number != null ? userProfile.ktp_number : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div className={styles.column6}> |
||||||
|
<div className={styles.gender}>Gender</div> |
||||||
|
<div className={styles.male}> |
||||||
|
{userProfile && userProfile.gender != null ? userProfile.gender : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div className={styles.row6}> |
||||||
|
<div className={styles.column7}> |
||||||
|
<div className={styles.division}>Division</div> |
||||||
|
<div className={styles.div2}> |
||||||
|
{userProfile && userProfile.join_first_name != null ? userProfile.join_first_name : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div className={styles.column8}> |
||||||
|
<div className={styles.placeOfBirth}>Place of Birth</div> |
||||||
|
<div className={styles.div3}> |
||||||
|
{userProfile && userProfile.birth_place != null ? userProfile.birth_place : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div className={styles.row7}> |
||||||
|
<div className={styles.column9}> |
||||||
|
<div className={styles.role}>Role</div> |
||||||
|
<div className={styles.div4}> |
||||||
|
{userProfile && userProfile.employee_type != null ? userProfile.employee_type : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div className={styles.column10}> |
||||||
|
<div className={styles.dateOfBirth}>Date of Birth</div> |
||||||
|
<div className={styles.div5}> |
||||||
|
{userProfile && userProfile.birth_date != null ? userProfile.birth_date : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div className={styles.row8}> |
||||||
|
<div className={styles.column11}> |
||||||
|
<div className={styles.address}>Address</div> |
||||||
|
<div className={styles.div6}> |
||||||
|
{userProfile && userProfile.address != null ? userProfile.address : <small style={{ fontStyle: 'italic', color:'gray' }}>empty</small>} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</footer> |
||||||
|
<Modal isOpen={modalOpen} toggle={toggleModal}> |
||||||
|
<ModalBody style={{ textAlign:'center' }}> |
||||||
|
{ |
||||||
|
imageProfile ? ( |
||||||
|
<img |
||||||
|
src={ |
||||||
|
imageProfile ? ( |
||||||
|
`${BASE_SIMPRO_LUMEN_IMAGE_COMPANY(imageProfile?.image, role != 'Super Admin' ? configApp.company_name : 'undifined')}` |
||||||
|
) : profile |
||||||
|
} |
||||||
|
style={{ maxWidth: "100%" }} |
||||||
|
alt="Image Preview" |
||||||
|
/> |
||||||
|
) : ('Image not found!') |
||||||
|
} |
||||||
|
</ModalBody> |
||||||
|
<ModalFooter> |
||||||
|
<Button color="secondary" onClick={toggleModal}>Close</Button> |
||||||
|
</ModalFooter> |
||||||
|
</Modal> |
||||||
|
</> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
export default Index; |
@ -0,0 +1,563 @@ |
|||||||
|
.codeReferal { |
||||||
|
position: relative; |
||||||
|
font-weight: 600; |
||||||
|
} |
||||||
|
.headTitle { |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
align-items: flex-start; |
||||||
|
justify-content: center; |
||||||
|
} |
||||||
|
.copyIcon, |
||||||
|
.ibnu212 { |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
.copyIcon { |
||||||
|
height: 16px; |
||||||
|
width: 16px; |
||||||
|
overflow: hidden; |
||||||
|
flex-shrink: 0; |
||||||
|
} |
||||||
|
.headSubtitle, |
||||||
|
.text { |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
align-items: center; |
||||||
|
justify-content: flex-start; |
||||||
|
gap: 0 10px; |
||||||
|
color: #777; |
||||||
|
} |
||||||
|
.text { |
||||||
|
flex: 1; |
||||||
|
flex-direction: column; |
||||||
|
align-items: flex-start; |
||||||
|
justify-content: center; |
||||||
|
gap: 5px 0; |
||||||
|
min-width: 640px; |
||||||
|
max-width: 100%; |
||||||
|
color: #333; |
||||||
|
} |
||||||
|
.copyIcon1 { |
||||||
|
height: 24px; |
||||||
|
width: 24px; |
||||||
|
position: relative; |
||||||
|
overflow: hidden; |
||||||
|
flex-shrink: 0; |
||||||
|
} |
||||||
|
.copy { |
||||||
|
position: relative; |
||||||
|
font-weight: 600; |
||||||
|
} |
||||||
|
.btnEdit { |
||||||
|
border-radius: 20px; |
||||||
|
border: 1px solid #969696; |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
align-items: center; |
||||||
|
justify-content: flex-start; |
||||||
|
padding: 5px 11px 5px 9px; |
||||||
|
gap: 0 11px; |
||||||
|
} |
||||||
|
.editTextIcon { |
||||||
|
height: 20px; |
||||||
|
width: 18px; |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
.icon { |
||||||
|
overflow: hidden; |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
align-items: flex-start; |
||||||
|
justify-content: flex-start; |
||||||
|
padding: 5px 8px; |
||||||
|
box-sizing: border-box; |
||||||
|
width: 24px; |
||||||
|
height: 24px; |
||||||
|
} |
||||||
|
.edit { |
||||||
|
position: relative; |
||||||
|
font-weight: 600; |
||||||
|
} |
||||||
|
.btnEdit1, |
||||||
|
.column { |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
align-items: center; |
||||||
|
justify-content: flex-start; |
||||||
|
} |
||||||
|
.btnEdit1 { |
||||||
|
border-radius: 20px; |
||||||
|
border: 1px solid #969696; |
||||||
|
padding: 5px 11px 5px 9px; |
||||||
|
gap: 0 11px; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
.column { |
||||||
|
align-self: stretch; |
||||||
|
background-color: #fff; |
||||||
|
border: 1px solid #7eacd3; |
||||||
|
box-sizing: border-box; |
||||||
|
flex-wrap: wrap; |
||||||
|
padding: 20px 21px 20px 19px; |
||||||
|
gap: 0 20px; |
||||||
|
max-width: 100%; |
||||||
|
} |
||||||
|
.accountInformation { |
||||||
|
position: relative; |
||||||
|
font-weight: 600; |
||||||
|
} |
||||||
|
.icon2 { |
||||||
|
height: 20px; |
||||||
|
width: 18px; |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
.icon1 { |
||||||
|
overflow: hidden; |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
align-items: flex-start; |
||||||
|
justify-content: flex-start; |
||||||
|
padding: 5px 8px; |
||||||
|
box-sizing: border-box; |
||||||
|
width: 24px; |
||||||
|
height: 24px; |
||||||
|
} |
||||||
|
.edit1 { |
||||||
|
position: relative; |
||||||
|
font-weight: 600; |
||||||
|
} |
||||||
|
.btnEdit2, |
||||||
|
.column1 { |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
} |
||||||
|
.btnEdit2 { |
||||||
|
border-radius: 20px; |
||||||
|
border: 1px solid #969696; |
||||||
|
align-items: center; |
||||||
|
justify-content: flex-start; |
||||||
|
padding: 5px 11px 5px 9px; |
||||||
|
gap: 0 11px; |
||||||
|
color: #969696; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
.column1 { |
||||||
|
align-self: stretch; |
||||||
|
align-items: flex-start; |
||||||
|
justify-content: space-between; |
||||||
|
gap: 20px; |
||||||
|
} |
||||||
|
.ibnu, |
||||||
|
.username { |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
.username { |
||||||
|
font-weight: 500; |
||||||
|
} |
||||||
|
.ibnu { |
||||||
|
color: #777; |
||||||
|
} |
||||||
|
.usernameParent { |
||||||
|
flex: 1; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
align-items: flex-start; |
||||||
|
justify-content: flex-start; |
||||||
|
gap: 10px 0; |
||||||
|
min-width: 378px; |
||||||
|
max-width: 100%; |
||||||
|
} |
||||||
|
.email { |
||||||
|
position: relative; |
||||||
|
font-weight: 500; |
||||||
|
} |
||||||
|
.emailContent { |
||||||
|
position: relative; |
||||||
|
color: #777; |
||||||
|
white-space: nowrap; |
||||||
|
} |
||||||
|
.emailParent, |
||||||
|
.frameParent { |
||||||
|
display: flex; |
||||||
|
align-items: flex-start; |
||||||
|
justify-content: flex-start; |
||||||
|
max-width: 100%; |
||||||
|
} |
||||||
|
.emailParent { |
||||||
|
flex: 1; |
||||||
|
flex-direction: column; |
||||||
|
gap: 10px 0; |
||||||
|
min-width: 378px; |
||||||
|
} |
||||||
|
.frameParent { |
||||||
|
align-self: stretch; |
||||||
|
flex-direction: row; |
||||||
|
flex-wrap: wrap; |
||||||
|
padding: 0 1px 0 0; |
||||||
|
box-sizing: border-box; |
||||||
|
gap: 0 37px; |
||||||
|
} |
||||||
|
.column2, |
||||||
|
.row, |
||||||
|
.row1 { |
||||||
|
align-self: stretch; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
align-items: flex-start; |
||||||
|
justify-content: flex-start; |
||||||
|
max-width: 100%; |
||||||
|
} |
||||||
|
.row1 { |
||||||
|
background-color: #fff; |
||||||
|
border: 1px solid #7eacd3; |
||||||
|
box-sizing: border-box; |
||||||
|
padding: 20px 21px 20px 19px; |
||||||
|
gap: 10px 0; |
||||||
|
color: #333; |
||||||
|
} |
||||||
|
.row { |
||||||
|
gap: 15px 0; |
||||||
|
} |
||||||
|
.personalInformation { |
||||||
|
position: relative; |
||||||
|
font-weight: 500; |
||||||
|
} |
||||||
|
.vectorIcon { |
||||||
|
height: 20px; |
||||||
|
width: 18px; |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
.icon3 { |
||||||
|
overflow: hidden; |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
align-items: flex-start; |
||||||
|
justify-content: flex-start; |
||||||
|
padding: 5px 8px; |
||||||
|
box-sizing: border-box; |
||||||
|
width: 24px; |
||||||
|
height: 24px; |
||||||
|
} |
||||||
|
.edit2 { |
||||||
|
position: relative; |
||||||
|
font-weight: 600; |
||||||
|
} |
||||||
|
.btnEdit3, |
||||||
|
.row3 { |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
} |
||||||
|
.btnEdit3 { |
||||||
|
border-radius: 20px; |
||||||
|
border: 1px solid #969696; |
||||||
|
align-items: center; |
||||||
|
justify-content: flex-start; |
||||||
|
padding: 5px 11px 5px 9px; |
||||||
|
gap: 0 11px; |
||||||
|
color: #969696; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
.row3 { |
||||||
|
align-self: stretch; |
||||||
|
align-items: flex-start; |
||||||
|
justify-content: space-between; |
||||||
|
gap: 20px; |
||||||
|
} |
||||||
|
.name { |
||||||
|
position: relative; |
||||||
|
font-weight: 500; |
||||||
|
} |
||||||
|
.content { |
||||||
|
position: relative; |
||||||
|
color: #777; |
||||||
|
} |
||||||
|
.column3 { |
||||||
|
flex: 1; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
align-items: flex-start; |
||||||
|
justify-content: flex-start; |
||||||
|
gap: 10px 0; |
||||||
|
min-width: 378px; |
||||||
|
max-width: 100%; |
||||||
|
} |
||||||
|
.noHp { |
||||||
|
position: relative; |
||||||
|
font-weight: 500; |
||||||
|
} |
||||||
|
.birthDetailsColumn { |
||||||
|
position: relative; |
||||||
|
color: #777; |
||||||
|
} |
||||||
|
.column4, |
||||||
|
.row4 { |
||||||
|
display: flex; |
||||||
|
align-items: flex-start; |
||||||
|
justify-content: flex-start; |
||||||
|
max-width: 100%; |
||||||
|
} |
||||||
|
.column4 { |
||||||
|
flex: 1; |
||||||
|
flex-direction: column; |
||||||
|
gap: 10px 0; |
||||||
|
min-width: 378px; |
||||||
|
} |
||||||
|
.row4 { |
||||||
|
align-self: stretch; |
||||||
|
flex-direction: row; |
||||||
|
flex-wrap: wrap; |
||||||
|
padding: 0 1px 0 0; |
||||||
|
box-sizing: border-box; |
||||||
|
gap: 0 37px; |
||||||
|
} |
||||||
|
.div1, |
||||||
|
.idNumber { |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
.idNumber { |
||||||
|
font-weight: 500; |
||||||
|
} |
||||||
|
.div1 { |
||||||
|
color: #777; |
||||||
|
} |
||||||
|
.column5 { |
||||||
|
flex: 1; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
align-items: flex-start; |
||||||
|
justify-content: flex-start; |
||||||
|
gap: 10px 0; |
||||||
|
min-width: 378px; |
||||||
|
max-width: 100%; |
||||||
|
} |
||||||
|
.gender, |
||||||
|
.male { |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
.gender { |
||||||
|
font-weight: 500; |
||||||
|
} |
||||||
|
.male { |
||||||
|
color: #777; |
||||||
|
} |
||||||
|
.column6, |
||||||
|
.row5 { |
||||||
|
display: flex; |
||||||
|
align-items: flex-start; |
||||||
|
justify-content: flex-start; |
||||||
|
max-width: 100%; |
||||||
|
} |
||||||
|
.column6 { |
||||||
|
flex: 1; |
||||||
|
flex-direction: column; |
||||||
|
gap: 10px 0; |
||||||
|
min-width: 378px; |
||||||
|
} |
||||||
|
.row5 { |
||||||
|
align-self: stretch; |
||||||
|
flex-direction: row; |
||||||
|
flex-wrap: wrap; |
||||||
|
padding: 0 1px 0 0; |
||||||
|
box-sizing: border-box; |
||||||
|
gap: 0 37px; |
||||||
|
} |
||||||
|
.div2, |
||||||
|
.division { |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
.division { |
||||||
|
font-weight: 500; |
||||||
|
} |
||||||
|
.div2 { |
||||||
|
color: #777; |
||||||
|
} |
||||||
|
.column7 { |
||||||
|
flex: 1; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
align-items: flex-start; |
||||||
|
justify-content: flex-start; |
||||||
|
gap: 10px 0; |
||||||
|
min-width: 378px; |
||||||
|
max-width: 100%; |
||||||
|
} |
||||||
|
.placeOfBirth { |
||||||
|
position: relative; |
||||||
|
font-weight: 500; |
||||||
|
} |
||||||
|
.div3 { |
||||||
|
position: relative; |
||||||
|
color: #777; |
||||||
|
} |
||||||
|
.column8, |
||||||
|
.row6 { |
||||||
|
display: flex; |
||||||
|
align-items: flex-start; |
||||||
|
justify-content: flex-start; |
||||||
|
max-width: 100%; |
||||||
|
} |
||||||
|
.column8 { |
||||||
|
flex: 1; |
||||||
|
flex-direction: column; |
||||||
|
gap: 10px 0; |
||||||
|
min-width: 378px; |
||||||
|
} |
||||||
|
.row6 { |
||||||
|
align-self: stretch; |
||||||
|
flex-direction: row; |
||||||
|
flex-wrap: wrap; |
||||||
|
padding: 0 1px 0 0; |
||||||
|
box-sizing: border-box; |
||||||
|
gap: 0 37px; |
||||||
|
} |
||||||
|
.div4, |
||||||
|
.role { |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
.role { |
||||||
|
font-weight: 500; |
||||||
|
} |
||||||
|
.div4 { |
||||||
|
color: #777; |
||||||
|
} |
||||||
|
.column9 { |
||||||
|
flex: 1; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
align-items: flex-start; |
||||||
|
justify-content: flex-start; |
||||||
|
gap: 10px 0; |
||||||
|
min-width: 378px; |
||||||
|
max-width: 100%; |
||||||
|
} |
||||||
|
.dateOfBirth { |
||||||
|
position: relative; |
||||||
|
font-weight: 500; |
||||||
|
} |
||||||
|
.div5 { |
||||||
|
position: relative; |
||||||
|
color: #777; |
||||||
|
} |
||||||
|
.column10, |
||||||
|
.row7 { |
||||||
|
display: flex; |
||||||
|
align-items: flex-start; |
||||||
|
justify-content: flex-start; |
||||||
|
max-width: 100%; |
||||||
|
} |
||||||
|
.column10 { |
||||||
|
flex: 1; |
||||||
|
flex-direction: column; |
||||||
|
gap: 10px 0; |
||||||
|
min-width: 378px; |
||||||
|
} |
||||||
|
.row7 { |
||||||
|
align-self: stretch; |
||||||
|
flex-direction: row; |
||||||
|
flex-wrap: wrap; |
||||||
|
padding: 0 1px 0 0; |
||||||
|
box-sizing: border-box; |
||||||
|
gap: 0 37px; |
||||||
|
} |
||||||
|
.address { |
||||||
|
font-weight: 500; |
||||||
|
} |
||||||
|
.address, |
||||||
|
.div6 { |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
.div6 { |
||||||
|
color: #777; |
||||||
|
} |
||||||
|
.column11, |
||||||
|
.row8 { |
||||||
|
display: flex; |
||||||
|
align-items: flex-start; |
||||||
|
justify-content: flex-start; |
||||||
|
max-width: 100%; |
||||||
|
} |
||||||
|
.column11 { |
||||||
|
flex: 1; |
||||||
|
flex-direction: column; |
||||||
|
gap: 10px 0; |
||||||
|
} |
||||||
|
.row8 { |
||||||
|
align-self: stretch; |
||||||
|
flex-direction: row; |
||||||
|
} |
||||||
|
.div { |
||||||
|
gap: 20px 0; |
||||||
|
} |
||||||
|
.div, |
||||||
|
.index1, |
||||||
|
.row2 { |
||||||
|
align-self: stretch; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
align-items: flex-start; |
||||||
|
justify-content: flex-start; |
||||||
|
max-width: 100%; |
||||||
|
} |
||||||
|
.row2 { |
||||||
|
background-color: #fff; |
||||||
|
border: 1px solid #7eacd3; |
||||||
|
box-sizing: border-box; |
||||||
|
padding: 20px 21px 20px 19px; |
||||||
|
gap: 10px 0; |
||||||
|
color: #333; |
||||||
|
} |
||||||
|
.index1 { |
||||||
|
gap: 15px 0; |
||||||
|
text-align: left; |
||||||
|
font-size: 16px; |
||||||
|
color: #969696; |
||||||
|
} |
||||||
|
@media screen and (max-width: 1050px) { |
||||||
|
.text { |
||||||
|
min-width: 100%; |
||||||
|
} |
||||||
|
} |
||||||
|
@media screen and (max-width: 750px) { |
||||||
|
.emailParent, |
||||||
|
.usernameParent { |
||||||
|
min-width: 100%; |
||||||
|
} |
||||||
|
.frameParent { |
||||||
|
gap: 0 37px; |
||||||
|
} |
||||||
|
.column3, |
||||||
|
.column4 { |
||||||
|
min-width: 100%; |
||||||
|
} |
||||||
|
.row4 { |
||||||
|
gap: 0 37px; |
||||||
|
} |
||||||
|
.column5, |
||||||
|
.column6 { |
||||||
|
min-width: 100%; |
||||||
|
} |
||||||
|
.row5 { |
||||||
|
gap: 0 37px; |
||||||
|
} |
||||||
|
.column7, |
||||||
|
.column8 { |
||||||
|
min-width: 100%; |
||||||
|
} |
||||||
|
.row6 { |
||||||
|
gap: 0 37px; |
||||||
|
} |
||||||
|
.column10, |
||||||
|
.column9 { |
||||||
|
min-width: 100%; |
||||||
|
} |
||||||
|
.row7, |
||||||
|
.row8 { |
||||||
|
gap: 0 37px; |
||||||
|
} |
||||||
|
} |
||||||
|
@media screen and (max-width: 450px) { |
||||||
|
.column1, |
||||||
|
.row3 { |
||||||
|
flex-wrap: wrap; |
||||||
|
} |
||||||
|
} |
@ -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; |
@ -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; |
||||||
|
} |
@ -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; |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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; |
@ -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; |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue