data karyawan

This commit is contained in:
Zamzam Nurzaman 2024-08-23 17:09:37 +07:00
parent 072c114e95
commit f9da238d9d
18 changed files with 819 additions and 26 deletions

View File

@ -1812,4 +1812,8 @@ section {
.ant-dropdown .ant-dropdown-menu .ant-dropdown-menu-submenu-title,
.ant-dropdown-menu-submenu .ant-dropdown-menu .ant-dropdown-menu-submenu-title {
padding: 0;
}
.ant-spin .ant-spin-dot-holder {
color: var(--primary);
}

View File

@ -160,7 +160,7 @@
.content-notif {
position: absolute;
position: relative;
z-index: 1;
top: 0;
width: 100%;

View File

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 79 KiB

View File

@ -1 +1 @@
{"version":3,"file":"sw.js","sources":["C:/Users/Zame/AppData/Local/Temp/900f456c4aacb311f0fcbfdfe76f4a59/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from 'E:/JS PROJECT/das/node_modules/workbox-routing/registerRoute.mjs';\nimport {NetworkFirst as workbox_strategies_NetworkFirst} from 'E:/JS PROJECT/das/node_modules/workbox-strategies/NetworkFirst.mjs';\nimport {NetworkOnly as workbox_strategies_NetworkOnly} from 'E:/JS PROJECT/das/node_modules/workbox-strategies/NetworkOnly.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from 'E:/JS PROJECT/das/node_modules/workbox-core/clientsClaim.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\nimportScripts(\n \n);\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n\nworkbox_routing_registerRoute(\"/\", new workbox_strategies_NetworkFirst({ \"cacheName\":\"start-url\", plugins: [{ cacheWillUpdate: async ({ request, response, event, state }) => { if (response && response.type === 'opaqueredirect') { return new Response(response.body, { status: 200, statusText: 'OK', headers: response.headers }) } return response } }] }), 'GET');\nworkbox_routing_registerRoute(/.*/i, new workbox_strategies_NetworkOnly({ \"cacheName\":\"dev\", plugins: [] }), 'GET');\n\n\n\n\n"],"names":["importScripts","self","skipWaiting","workbox_core_clientsClaim","workbox_routing_registerRoute","workbox_strategies_NetworkFirst","plugins","cacheWillUpdate","request","response","event","state","type","Response","body","status","statusText","headers","workbox_strategies_NetworkOnly"],"mappings":"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"}
{"version":3,"file":"sw.js","sources":["C:/Users/Zame/AppData/Local/Temp/921224a5bd3165d633a1c85bf0fdd625/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from 'E:/JS PROJECT/das/node_modules/workbox-routing/registerRoute.mjs';\nimport {NetworkFirst as workbox_strategies_NetworkFirst} from 'E:/JS PROJECT/das/node_modules/workbox-strategies/NetworkFirst.mjs';\nimport {NetworkOnly as workbox_strategies_NetworkOnly} from 'E:/JS PROJECT/das/node_modules/workbox-strategies/NetworkOnly.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from 'E:/JS PROJECT/das/node_modules/workbox-core/clientsClaim.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\nimportScripts(\n \n);\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n\nworkbox_routing_registerRoute(\"/\", new workbox_strategies_NetworkFirst({ \"cacheName\":\"start-url\", plugins: [{ cacheWillUpdate: async ({ request, response, event, state }) => { if (response && response.type === 'opaqueredirect') { return new Response(response.body, { status: 200, statusText: 'OK', headers: response.headers }) } return response } }] }), 'GET');\nworkbox_routing_registerRoute(/.*/i, new workbox_strategies_NetworkOnly({ \"cacheName\":\"dev\", plugins: [] }), 'GET');\n\n\n\n\n"],"names":["importScripts","self","skipWaiting","workbox_core_clientsClaim","workbox_routing_registerRoute","workbox_strategies_NetworkFirst","plugins","cacheWillUpdate","request","response","event","state","type","Response","body","status","statusText","headers","workbox_strategies_NetworkOnly"],"mappings":"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"}

View File

@ -0,0 +1,77 @@
import React, {useEffect, useState} from "react";
import {Col, Dropdown, Row} from "antd";
import "./style.scss";
import {CheckCircleOutlined, CloseCircleOutlined, ContainerOutlined, EditOutlined, SettingOutlined, UserOutlined} from "@ant-design/icons";
export default function CardKaryawan({data,modalOpen}) {
return (<Row gutter={[20, 5]}>
{data && data?.map((v, k) => {
let items = [
{
key: '1',
label: (<button onClick={() => modalOpen(v?.karyawanId,'edit')} className="dropdown-item w-full">
<EditOutlined className="text-muted me-2"/>Ubah
</button>),
},
{
key: '2',
label: (<button onClick={() => modalOpen(v?.karyawanId,'detail')} className="dropdown-item w-full">
<ContainerOutlined className="text-muted me-2"/>Detail
</button>),
}
]
return (<Col key={k} span={6}>
<div className="card-karyawan">
<div className={"content-title"}>
<div className={"name"}>{v?.karyawanNm}</div>
<div className={"position"}>{v?.jabatanNm}</div>
</div>
<div className={"container-karyawan"}>
<div className={"content-karyawan"}>
<div className={"title"}>NIK</div>
<div className={"value"}>{v?.nik}</div>
</div>
<div className={"content-karyawan"}>
<div className={"title"}>username</div>
<div className={"value"}>{v?.username}</div>
</div>
<div className={"content-karyawan"}>
<div className={"title"}>telpon/hp</div>
<div className={"value"}>{v?.phoneNo}</div>
</div>
</div>
<div className={"content-btn"}>
<Dropdown trigger={["click"]} placement="bottomLeft" arrow menu={{items}}>
<button type="button" className="btn btn-primary my-1 btn-sm" data-bs-toggle="dropdown">
<SettingOutlined/> Pengaturan
</button>
</Dropdown>
</div>
<div className={`content-status ${(v?.isActive) ? 'bg-success-light' : 'bg-danger-light'}`}>
{(v?.isActive) ? <div className={"status-flag text-success"}>
<CheckCircleOutlined className="text-success me-2"/>
<div>Aktif</div>
</div> : <div className={"status-flag text-danger"}>
<CloseCircleOutlined className="text-danger me-2"/>
<div>Tidak Aktif</div>
</div>}
</div>
<div className={"content-foto"}>
{(v?.profilePict) ? <img alt={"karyawan"} className={"img"} src={v?.profilePict}/> : <UserOutlined className={"icon"}/>}
</div>
</div>
</Col>
)
})}
</Row>)
}

View File

@ -0,0 +1,157 @@
import {Col, Modal, Row, Spin} from "antd";
import {CloseOutlined} from "@ant-design/icons";
import Input from "@/components/util/Input";
import React, {useEffect, useState} from "react";
import {useForm} from "react-hook-form";
import {Helper} from "@/lib/Helper";
import {DropdownAPI} from "@/lib/DropdownAPI";
export default function FormKaryawan({modalStatus, actClose, data, loadingModal,jenis}) {
const [viewReadonly, setViewReadonly] = useState(false)
const [dropdownLoading, setDropdownLoading] = useState(false)
const [dropdown, setDropdown] = useState(
{
roleId : [],
branchId : [],
jabatanId : [],
jenisKelaminId : [],
agamaId : [],
statusKaryawanId : []
}
)
const {
register, setValue, watch, getValues, formState: {errors},
} = useForm();
const dropdownInit = async () => {
setDropdownLoading(true)
let listRole = await DropdownAPI.role();
let listBranch = await DropdownAPI.cabang();
let listJabatan = await DropdownAPI.jabatan();
let listJenisKelamin = await DropdownAPI.jenisKelamin();
let listAgama = await DropdownAPI.agama();
let listStatusKaryawan = await DropdownAPI.statusKaryawan();
setDropdown({
roleId : listRole,
branchId : listBranch,
jabatanId : listJabatan,
jenisKelaminId :listJenisKelamin,
agamaId : listAgama,
statusKaryawanId : listStatusKaryawan
})
setDropdownLoading(false)
}
const TypeAction = () => {
if(jenis === 'detail'){
return(
<></>
)
}else{
return(
<button className="btn btn-primary btn-sm">Simpan</button>
)
}
}
useEffect(() => {
if (jenis === 'detail'){
setViewReadonly(true);
}else{
setViewReadonly(false);
}
}, [jenis]);
useEffect(() => {
if (data){
setValue('karyawanNm',data?.karyawanNm)
setValue('roleId',data?.roleId)
}
}, [data]);
useEffect(() => {
dropdownInit()
}, []);
return (<Modal centered closeIcon={false} open={modalStatus} width={"1200px"} footer={null}>
<Spin spinning={loadingModal}>
<div className="btn btn-circle btn-light-primary zn-close" onClick={actClose}>
<CloseOutlined/>
</div>
<div className="px-6 py-4 cardDark">
<div className="fs-6 fw-bolder text-uppercase text-primary">Data Karyawan</div>
<div className="fs-7 fw-ligth text-muted">Data Karyawan</div>
<div className="separator my-3"/>
<div style={{overflowY:'auto',overflowX:'hidden',height:'600px'}} className="my-4 p-2">
<Row gutter={15}>
<Col span={6}>
<Input.Text title={"Nama Karyawan"} name={"karyawanNm"} minlength={"15"} maxlength={"100"} setReadonly={viewReadonly} required register={register} error={errors}/>
</Col>
<Col span={6}>
<Input.Text title={"Username"} name={"username"} minlength={"15"} maxlength={"100"} setReadonly={viewReadonly} required register={register} error={errors}/>
</Col>
<Col span={6}>
<Input.Select title={"Wewenang"} name={"roleId"} val={watch("roleId")} loading={dropdownLoading} options={dropdown?.roleId} setValue={setValue} setReadonly={viewReadonly} required register={register} error={errors}/>
</Col>
<Col span={6}>
<Input.Text title={"Karyawan"} name={"email"} minlength={"15"} maxlength={"100"} setReadonly={viewReadonly} required register={register} error={errors}/>
</Col>
<Col span={6}>
<Input.Text title={"Karyawan"} name={"phoneNo"} minlength={"15"} maxlength={"100"} setReadonly={viewReadonly} required register={register} error={errors}/>
</Col>
<Col span={6}>
<Input.Text title={"Karyawan"} name={"branchId"} minlength={"15"} maxlength={"100"} setReadonly={viewReadonly} required register={register} error={errors}/>
</Col>
<Col span={6}>
<Input.Text title={"Karyawan"} name={"jabatanId"} minlength={"15"} maxlength={"100"} setReadonly={viewReadonly} required register={register} error={errors}/>
</Col>
<Col span={6}>
<Input.Text title={"Karyawan"} name={"nik"} minlength={"15"} maxlength={"100"} setReadonly={viewReadonly} required register={register} error={errors}/>
</Col>
<Col span={6}>
<Input.Text title={"Karyawan"} name={"nip"} minlength={"15"} maxlength={"100"} setReadonly={viewReadonly} required register={register} error={errors}/>
</Col>
<Col span={6}>
<Input.Text title={"Karyawan"} name={"npwp"} minlength={"15"} maxlength={"100"} setReadonly={viewReadonly} required register={register} error={errors}/>
</Col>
<Col span={6}>
<Input.Text title={"Karyawan"} name={"birthPlace"} minlength={"15"} maxlength={"100"} setReadonly={viewReadonly} required register={register} error={errors}/>
</Col>
<Col span={6}>
<Input.Text title={"Karyawan"} name={"birthDt"} minlength={"15"} maxlength={"100"} setReadonly={viewReadonly} required register={register} error={errors}/>
</Col>
<Col span={6}>
<Input.Text title={"Karyawan"} name={"address"} minlength={"15"} maxlength={"100"} setReadonly={viewReadonly} required register={register} error={errors}/>
</Col>
<Col span={6}>
<Input.Text title={"Karyawan"} name={"tanggalBekerja"} minlength={"15"} maxlength={"100"} setReadonly={viewReadonly} required register={register} error={errors}/>
</Col>
<Col span={6}>
<Input.Text title={"Karyawan"} name={"jenisKelaminId"} minlength={"15"} maxlength={"100"} setReadonly={viewReadonly} required register={register} error={errors}/>
</Col>
<Col span={6}>
<Input.Text title={"Karyawan"} name={"agamaId"} minlength={"15"} maxlength={"100"} setReadonly={viewReadonly} required register={register} error={errors}/>
</Col>
<Col span={6}>
<Input.Text title={"Karyawan"} name={"statusKaryawanId"} minlength={"15"} maxlength={"100"} setReadonly={viewReadonly} required register={register} error={errors}/>
</Col>
</Row>
</div>
</div>
<div className="card-footer text-right py-3 px-5 zn-bg-modal">
<TypeAction/>
</div>
</Spin>
</Modal>
)
}

View File

@ -0,0 +1,98 @@
"use client"
import SearchInput from "@/components/util/SearchInput";
import WrapperContent from "@/components/util/WrapperContent";
import React, {useEffect, useState} from "react";
import CardKaryawan from "./CardKaryawan";
import {API} from "@/lib/API";
import notifStore from "@/store/notifStore";
import {Modal, Spin} from "antd";
import {CloseOutlined} from "@ant-design/icons";
import FormKaryawan from "@/app/main/karyawan/dataKaryawan/daftarKaryawan/FormKaryawan";
export default function DaftarKaryawan() {
const {notifOpen} = notifStore()
const [searchText, setSearchText] = useState(null)
const [dataKaryawan, setDataKaryawan] = useState([])
const [modalKaryawan, setModalKaryawan] = useState({
loadingModal:false,
modalStatus:false,
jenis:null,
data:[]
})
const handleSearch = (event) => {
const handler = setTimeout(() => {
setSearchText(event.target.value);
}, 1000);
return () => {
clearTimeout(handler);
};
};
const getKaryawan = async () => {
let res = await API.GET('/ref/karyawan')
if(res.status !== 200){
notifOpen("Gagal", res.result.message, "danger");
return false
}
setDataKaryawan(res.result.data)
}
const modalOpen = async (id,type) => {
setModalKaryawan(prev => ({
...prev,
modalStatus: true,
jenis: type,
loadingModal: true
}));
let res = await API.GET('/ref/karyawan/'+id)
setModalKaryawan(prev => ({
...prev,
data: res.result,
loadingModal: false
}));
}
useEffect(() => {
getKaryawan()
}, []);
return(<>
<WrapperContent>
<div className="containers">
<div className="headContent">
<div className="containerTitle">
<div className="breadCrumb">
<div className="text">Data Karyawan</div>
<div className="text">Daftar Karyawan</div>
</div>
<div className="title text-dark-grey left">Daftar Karyawan</div>
</div>
<div className="filter mb-3">
<SearchInput handleSearch={handleSearch} style={{marginRight: "10px"}}/>
</div>
</div>
<div className="bodyContent">
<CardKaryawan modalOpen={modalOpen} data={dataKaryawan}/>
</div>
</div>
</WrapperContent>
<FormKaryawan
loadingModal={modalKaryawan?.loadingModal}
modalStatus={modalKaryawan?.modalStatus}
jenis={modalKaryawan?.jenis}
actClose={()=>{
setModalKaryawan(prev => ({
...prev,
modalStatus: false,
loadingModal: false
}));
}}
data={modalKaryawan?.data} />
</>)
}

View File

@ -0,0 +1,80 @@
.card-karyawan{
background: #fff;
padding: 10px;
border-radius: 25px;
box-shadow: 0px 8px 50px #00000005;
margin-top: 15px;
transition: 0.5s ease-in-out;
&:hover{
box-shadow: 0px 25px 50px rgb(0 0 0 / 15%);
}
.content-title{
background: #f7f7f7;
padding: 10px 15px;
border-radius: 20px;
width: 60%;
.name{
font-weight: 600;
font-size: 14px;
color: var(--dark);
}
.position{
font-weight: 400;
font-size: 12px;
color: var(--text-muted);
}
}
.container-karyawan{
padding: 15px;
}
.content-karyawan{
margin-bottom: 15px;
.title{
font-size: 12px;
font-weight: 400;
color: var(--text-muted);
}
.value{
font-size: 13px;
font-weight: 500;
color: #0c111c;
}
}
.content-status{
position: absolute;
top: 5px;
right: 20px;
border-radius: 20px;
padding: 3px 30px 3px 10px;
.status-flag{
display: flex;
gap: 0px;
font-weight: 400;
font-size: 12px;
}
}
.content-foto{
position: absolute;
bottom: 10px;
right: 5px;
.icon{
font-size: 180px;
color: rgba(0, 0, 0, 0.05);
}
.img{
width: 150px;
object-fit: contain;
}
}
}

View File

@ -0,0 +1,64 @@
"use client"
import {useEffect, useState} from "react";
import RefTemplate from "@/components/refTemplate/Main";
import {Helper} from "@/lib/Helper";
export default function Page() {
const [listForm, setListForm] = useState()
const initListForm = async () => {
// TYPE form
setListForm([
{
type: 'text',
name: 'divisiNm',
alias: 'Divisi',
maxLength: '150',
required: true,
col: 24
}])
}
useEffect(() => {
initListForm()
}, []);
return (
<>
<RefTemplate
refTitle="Data Karyawan"
refSubTitle="Divisi"
refEndPointAll="/ref/divisi"
listAction={['create', 'update','active', 'delete']}
primaryKey="divisiId"
columnTableRef={[
{
title: "ID",
dataIndex: 'divisiId',
width: '10%',
sorter: (a, b) => a.divisiId - b.divisiId
},
{
title: "Divisi",
dataIndex: 'divisiNm',
sorter: (a, b) => b.divisiNm.localeCompare(a.divisiNm)
},
{
title: "Update Terakhir",
render: (_, row) => (Helper.formatDate(row.uptdt,'d-M-Y H:i:s'))
},
{
title: "Status",
width: '5%',
render: (_, row) => (row.isActive === true ?
<span className="btn btn-light-success my-1 mx-1 btn-sm" style={{cursor: "none", height: "30px"}}>Aktif</span> :
<span className="btn btn-light-danger my-1 mx-1 btn-sm" style={{cursor: "none", height: "30px"}}>Tidak Aktif</span>)
},
]}
listForm={listForm}
/>
</>
)
}

View File

@ -0,0 +1,77 @@
"use client"
import {useEffect, useState} from "react";
import RefTemplate from "@/components/refTemplate/Main";
import {Helper} from "@/lib/Helper";
import {DropdownAPI} from "@/lib/DropdownAPI";
export default function Page() {
const [listForm, setListForm] = useState()
const initListForm = async () => {
let listDivisi = await DropdownAPI.divisi();
// TYPE form
setListForm([
{
type: 'select',
name: 'divisiId',
alias: 'Divisi',
required: true,
listData: listDivisi,
col: 24
},{
type: 'text',
name: 'jabatanNm',
alias: 'Jabatan ',
maxLength: '150',
required: true,
col: 24
}])
}
useEffect(() => {
initListForm()
}, []);
return (
<>
<RefTemplate
refTitle="Data Karyawan"
refSubTitle="Jabatan"
refEndPointAll="/ref/jabatan"
listAction={['create', 'update','active', 'delete']}
primaryKey="jabatanId"
columnTableRef={[
{
title: "ID",
dataIndex: 'jabatanId',
width: '10%',
sorter: (a, b) => a.jabatanId - b.jabatanId
},
{
title: "Divisi",
dataIndex: 'divisiNm',
sorter: (a, b) => b.divisiNm.localeCompare(a.divisiNm)
},
{
title: "Jabatan",
dataIndex: 'jabatanNm',
sorter: (a, b) => b.jabatanNm.localeCompare(a.jabatanNm)
},
{
title: "Update Terakhir",
render: (_, row) => (Helper.formatDate(row.uptdt,'d-M-Y H:i:s'))
},
{
title: "Status",
width: '5%',
render: (_, row) => (row.isActive === true ?
<span className="btn btn-light-success my-1 mx-1 btn-sm" style={{cursor: "none", height: "30px"}}>Aktif</span> :
<span className="btn btn-light-danger my-1 mx-1 btn-sm" style={{cursor: "none", height: "30px"}}>Tidak Aktif</span>)
},
]}
listForm={listForm}
/>
</>
)
}

View File

@ -0,0 +1,66 @@
"use client"
import {useEffect, useState} from "react";
import RefTemplate from "@/components/refTemplate/Main";
import {Helper} from "@/lib/Helper";
export default function Page() {
const [listForm, setListForm] = useState()
const initListForm = async () => {
// TYPE form
setListForm([
{
type: 'text',
name: 'statusKaryawanNm',
alias: 'Status Karyawan',
maxLength: '150',
required: true,
col: 24
}])
}
useEffect(() => {
initListForm()
}, []);
return (
<>
<RefTemplate
refTitle="Data Karyawan"
refSubTitle="Status Karyawan"
refEndPointAll="/ref/statusKaryawan"
listAction={['create', 'update', 'active','delete']}
primaryKey="statusKaryawanId"
columnTableRef={[
{
title: "ID",
dataIndex: 'statusKaryawanId',
key: 'statusKaryawanId',
width: '10%',
sorter: (a, b) => a.statusKaryawanId - b.statusKaryawanId
},
{
title: "Status Karyawan",
dataIndex: 'nm',
key: 'nm',
sorter: (a, b) => b.nm.localeCompare(a.nm)
},
{
title: "Update Terakhir",
render: (_, row) => (Helper.formatDate(row.uptdt,'d-M-Y H:i:s'))
},
{
title: "Status",
width: '5%',
render: (_, row) => (row.isActive === true ?
<span className="btn btn-light-success my-1 mx-1 btn-sm" style={{cursor: "none", height: "30px"}}>Aktif</span> :
<span className="btn btn-light-danger my-1 mx-1 btn-sm" style={{cursor: "none", height: "30px"}}>Tidak Aktif</span>)
},
]}
listForm={listForm}
/>
</>
)
}

View File

@ -0,0 +1,64 @@
"use client"
import {useEffect, useState} from "react";
import RefTemplate from "@/components/refTemplate/Main";
import {Helper} from "@/lib/Helper";
export default function Page() {
const [listForm, setListForm] = useState()
const initListForm = async () => {
// TYPE form
setListForm([
{
type: 'text',
name: 'divisiNm',
alias: 'Divisi',
maxLength: '150',
required: true,
col: 24
}])
}
useEffect(() => {
initListForm()
}, []);
return (
<>
<RefTemplate
refTitle="Data Karyawan"
refSubTitle="Divisi"
refEndPointAll="/ref/divisi"
listAction={['create', 'update','active', 'delete']}
primaryKey="divisiId"
columnTableRef={[
{
title: "ID",
dataIndex: 'divisiId',
width: '10%',
sorter: (a, b) => a.divisiId - b.divisiId
},
{
title: "Divisi",
dataIndex: 'divisiNm',
sorter: (a, b) => b.divisiNm.localeCompare(a.divisiNm)
},
{
title: "Update Terakhir",
render: (_, row) => (Helper.formatDate(row.uptdt,'d-M-Y H:i:s'))
},
{
title: "Status",
width: '5%',
render: (_, row) => (row.isActive === true ?
<span className="btn btn-light-success my-1 mx-1 btn-sm" style={{cursor: "none", height: "30px"}}>Aktif</span> :
<span className="btn btn-light-danger my-1 mx-1 btn-sm" style={{cursor: "none", height: "30px"}}>Tidak Aktif</span>)
},
]}
listForm={listForm}
/>
</>
)
}

View File

@ -0,0 +1,63 @@
"use client"
import {useEffect, useState} from "react";
import RefTemplate from "@/components/refTemplate/Main";
import {Helper} from "@/lib/Helper";
export default function Page() {
const [listForm, setListForm] = useState()
const initListForm = async () => {
// TYPE form
setListForm([
{
type: 'text',
name: 'divisiNm',
alias: 'Divisi',
maxLength: '150',
required: true,
col: 24
}])
}
useEffect(() => {
initListForm()
}, []);
return (
<>
<RefTemplate
refTitle="Referensi"
refSubTitle="Wilayah"
refEndPointAll="/ref/wilayah"
listAction={[]}
primaryKey="wilayahId"
serverSide={true}
columnTableRef={[
{
title: "ID",
dataIndex: 'wilayahId',
width: '10%',
},
{
title: "Wilayah",
dataIndex: 'wil',
},
{
title: "Update Terakhir",
render: (_, row) => ((row.uptdt) ? Helper.formatDate(row.uptdt,'d-M-Y H:i:s'):'-')
},
// {
// title: "Status",
// width: '5%',
// render: (_, row) => (row.isActive === true ?
// <span className="btn btn-light-success my-1 mx-1 btn-sm" style={{cursor: "none", height: "30px"}}>Aktif</span> :
// <span className="btn btn-light-danger my-1 mx-1 btn-sm" style={{cursor: "none", height: "30px"}}>Tidak Aktif</span>)
// },
]}
listForm={listForm}
/>
</>
)
}

View File

@ -219,22 +219,20 @@ const RefTemplate = ({
})
}
if (listAction.includes('active') && !isWaitingApproval) {
if (row.active) {
items.push({
key: "5", label: (<button className="dropdown-item w-full" onClick={() => setActiveData(row[primaryKey], false)}>
<CloseOutlined className="text-muted me-2"/>
Non Aktif
</button>),
});
} else {
items.push({
key: "4", label: (<button className="dropdown-item w-full" onClick={() => setActiveData(row[primaryKey], true)}>
<CheckOutlined className="text-muted me-2"/>
Aktif
</button>),
});
}
if (listAction.includes('active')) {
items.push({
key: '6',
label: (
(row.isActive) ?
<button onClick={() => activeData(row[primaryKey],row.isActive)} className="dropdown-item">
<CloseOutlined className="text-muted me-2"/>Nonaktifkan
</button>
:
<button onClick={() => activeData(row[primaryKey],row.isActive)} className="dropdown-item">
<CheckOutlined className="text-muted me-2"/>Aktifkan
</button>
),
})
}
if (listAction.includes('history_approval')) {

View File

@ -1,4 +1,4 @@
import {Select} from 'antd';
import {Select, Spin} from 'antd';
const InputSelect = ({
title,
@ -33,8 +33,10 @@ const InputSelect = ({
return (
<>
<Spin spinning={loading}>
<div className={`form-group mb-10 ${error[name]?.message ? "error" : ""}`}>
<div className="floating-label-content">
<Select
disabled={setReadonly || setDisabled}
// defaultValue="lucy"
@ -53,12 +55,14 @@ const InputSelect = ({
className="form-control borderInput floating-input"
options={options}
/>
<label className="floating-label" htmlFor={name}>
{title} {(required) ? <span className={"fw-7 text-danger"}>*</span>:''}
</label>
{error[name] && <div className="error-form">{error[name]?.message}</div>}
</div>
</div>
</Spin>
</>
);
};

View File

@ -7,7 +7,7 @@ export default function ModalConfirm() {
<>
<Modal centered closeIcon={false} open={confirmStat} footer={null} width='300px'>
<Spin spinning={confirmLoading}>
<div className="card wave wave-animate-slow wave-danger" style={{minHeight:'145px'}} >
<div className="card wave wave-animate-slow wave-danger" style={{padding:'5px'}} >
<div className="content-notif">
<div className="card-body py-3 px-4" >

View File

@ -23,7 +23,7 @@ export default function ModalNotif() {
return (
<>
<Modal centered closeIcon={false} open={notifStat} footer={null} width='300px' zIndex={10000}>
<div className={`card wave wave-animate-slow wave-${type}`} style={{minHeight: '120px'}}>
<div className={`card wave wave-animate-slow wave-${type}`} style={{padding: '5px'}}>
<div className="content-notif">
<div className="card-body py-5 px-4">

View File

@ -18,12 +18,49 @@ const cabang = async () => {
};
});
}
const productType = async () => {
let response = await API.GET(`/ref/productType`);
const divisi = async () => {
let response = await API.GET(`/ref/divisi`);
return response?.result?.data?.map((v) => {
return {
value: v.productTypeId,
label: v.definition,
value: v.divisiId,
label: v.divisiNm,
};
});
}
const agama = async () => {
let response = await API.GET(`/ref/agama`);
return response?.result?.data?.map((v) => {
return {
value: v.agamaId,
label: v.agamaNm,
};
});
}
const jabatan = async () => {
let response = await API.GET(`/ref/jabatan`);
return response?.result?.data?.map((v) => {
return {
value: v.jabatanId,
label: v.jabatanNm,
};
});
}
const jenisKelamin = async () => {
let response = await API.GET(`/ref/jenisKelamin`);
return response?.result?.data?.map((v) => {
return {
value: v.jenisKelaminId,
label: v.jenisKelaminNm,
};
});
}
const statusKaryawan = async () => {
let response = await API.GET(`/ref/statusKaryawan`);
return response?.result?.data?.map((v) => {
return {
value: v.statusKaryawanId,
label: v.statusKaryawanNm,
};
});
}
@ -31,5 +68,9 @@ const productType = async () => {
export const DropdownAPI = {
role,
cabang,
productType
divisi,
agama,
jabatan,
jenisKelamin,
statusKaryawan
};