Initial commit, repo migration

This commit is contained in:
unknown
2024-05-14 22:19:14 +07:00
commit b51b940ac4
137 changed files with 19393 additions and 0 deletions
+134
View File
@@ -0,0 +1,134 @@
import { AkunCreate, AkunUpdate } from '@/services/referensi/akun-service'
import { useFormik } from 'formik'
import { Button } from 'primereact/button'
import { Dialog } from 'primereact/dialog'
import { InputText } from 'primereact/inputtext'
export default function FormAkun({ dialogForm, setDialogForm, dataEdit, setDataEdit, refresh, toast }) {
const formik = useFormik({
initialValues: {
akun_id: dataEdit.akun_id || '',
nama: dataEdit.nama || '',
},
validate: (data) => {
let errors = {}
if (!data.akun_id) errors.akun_id = 'Error akun is required.'
if (!data.nama) errors.nama = 'Error name is required.'
return errors
},
onSubmit: (data) => {
if (data.akun_id) {
AkunUpdate(data).then((res) => {
if (res.status === 'success') {
refresh(Math.random)
formik.resetForm()
setDataEdit([])
setDialogForm(false)
toast.current.show({
severity: 'success',
detail: res.message,
closable: false,
})
} else {
setDialogForm(false)
toast.current.show({
severity: 'error',
detail: res.message,
closable: false,
})
}
})
} else {
AkunCreate(data).then((res) => {
if (res.status === 'success') {
refresh(Math.random)
formik.resetForm()
setDataEdit([])
setDialogForm(false)
toast.current.show({
severity: 'success',
detail: res.message,
closable: false,
})
} else {
setDialogForm(false)
toast.current.show({
severity: 'error',
detail: res.message,
closable: false,
})
}
})
}
},
})
const isFieldValid = (field) => !!(formik.touched[field] && formik.errors[field])
const errorFieldMessage = (field) => {
return (
isFieldValid(field) && (
<small className='p-error' style={{ fontSize: '11px' }}>
{formik.errors[field]}
</small>
)
)
}
const dialogFooter = (
<div className='flex justify-end'>
<Button
type='submit'
label='Cancel'
className='p-button-sm p-button-secondary'
onClick={() => {
formik.resetForm()
setDialogForm(false)
}}
/>
<Button type='submit' label='Save' className='p-button-sm p-button-primary' onClick={formik.handleSubmit} />
</div>
)
return (
<>
<Dialog
header={formik.values.akun_id ? 'Update Akun' : 'Add Akun'}
className='p-dialog-form'
visible={dialogForm}
draggable={false}
resizable={false}
position={'center'}
closable={false}
style={{ width: '30vw' }}
footer={dialogFooter}
>
<form onSubmit={formik.handleSubmit}>
<div className='p-fluid grid'>
<div className='field col-12 md:col-12 mb-3'>
<label className='block'>Nomor Akun</label>
<InputText
className='p-inputtext-sm'
name='akun_id'
value={formik.values.akun_id}
onChange={formik.handleChange}
placeholder='Nomor Akun'
/>
{errorFieldMessage('akun_id')}
</div>
<div className='field col-12 md:col-12 mb-0'>
<label className='block'>Nama Akun</label>
<InputText
className='p-inputtext-sm'
name='nama'
value={formik.values.nama}
onChange={formik.handleChange}
placeholder='Nama Akun'
/>
{errorFieldMessage('nama')}
</div>
</div>
</form>
</Dialog>
</>
)
}
+149
View File
@@ -0,0 +1,149 @@
import { JamKerjaCreate } from '@/services/manajemen/jam-kerja-service'
import { Formik } from 'formik'
import moment from 'moment'
import { Button } from 'primereact/button'
import { Calendar } from 'primereact/calendar'
import { Dialog } from 'primereact/dialog'
import { MultiSelect } from 'primereact/multiselect'
const dbHari = [
{ name: 'Senin', code: 'senin' },
{ name: 'Selasa', code: 'selasa' },
{ name: 'Rabu', code: 'rabu' },
{ name: 'Kamis', code: 'kamis' },
{ name: 'Jumat', code: 'jumat' },
{ name: 'Sabtu', code: 'sabtu' },
{ name: 'Minggu', code: 'minggu' },
]
export default function FormJamKerja({ dialogForm, setDialogForm, dataEdit, toast, refresh }) {
return (
<>
<Formik
initialValues={{
user_id: dataEdit.user_id || '',
hari: dataEdit.hari || null,
jam_masuk: dataEdit.jam_masuk || null,
jam_keluar: dataEdit.jam_keluar || null,
}}
onSubmit={(data, { setSubmitting }) => {
Object.assign(data, {
jam_masuk: moment(data.jam_masuk).format('HH:mm'),
jam_keluar: moment(data.jam_keluar).format('HH:mm'),
})
let time = data.jam_masuk + '-' + data.jam_keluar
let days = ''
let panjang_array = data.hari.length
data.hari.map((values, i) => {
let plus1 = i + 1
let koma = plus1 < panjang_array ? ',' : ''
days += values.code + koma
})
let dataKirim = { days, time }
JamKerjaCreate(dataKirim).then((res) => {
if (res.status === 'success') {
setDialogForm(false)
refresh(Math.random)
toast.current.show({
severity: 'success',
detail: res.message,
closable: false,
})
} else {
setDialogForm(false)
refresh(Math.random)
toast.current.show({
severity: 'error',
detail: res.message,
closable: false,
})
}
})
setSubmitting(false)
}}
validateOnChange={false}
>
{({ values, handleChange, handleSubmit, isSubmitting, resetForm }) => {
const dialogFooter = (
<div className='flex justify-end'>
<Button
type='submit'
label='Cancel'
className='p-button-sm p-button-secondary'
onClick={() => {
resetForm()
setDialogForm(false)
}}
/>
<Button
type='submit'
label='Save'
className='p-button-sm p-button-primary'
onClick={handleSubmit}
loading={isSubmitting}
/>
</div>
)
return (
<Dialog
header={values.user_id ? 'Update Jam Kerja' : 'Add Jam Kerja'}
className='p-dialog-form'
visible={dialogForm}
draggable={false}
resizable={false}
position={'center'}
closable={false}
style={{ width: '30vw' }}
footer={dialogFooter}
>
<form onSubmit={handleSubmit}>
<div className='p-fluid grid'>
<div className='field col-12 md:col-12 mb-2'>
<label className='block'>Pilih Hari</label>
<MultiSelect
id='hari'
value={values.hari}
onChange={handleChange}
options={dbHari}
optionLabel='name'
placeholder='Select Hari'
maxSelectedLabels={3}
className='w-full md:w-20rem'
/>
</div>
<div className='grid grid-cols-2 gap-3'>
<div className='mb-2'>
<label className='block'>Jam Masuk</label>
<Calendar
id='jam_masuk'
value={values.jam_masuk}
onChange={handleChange}
placeholder='Masukkan Jam Masuk'
timeOnly
hourFormat='24'
/>
</div>
<div className='mb-2'>
<label className='block'>Jam Keluar</label>
<Calendar
id='jam_keluar'
value={values.jam_keluar}
onChange={handleChange}
placeholder='Masukkan Jam Keluar'
timeOnly
hourFormat='24'
minDate={values.jam_masuk}
disabled={values.jam_masuk ? false : true}
/>
</div>
</div>
</div>
</form>
</Dialog>
)
}}
</Formik>
</>
)
}
+122
View File
@@ -0,0 +1,122 @@
import { JenisBelanjaCreate, JenisBelanjaUpdate } from '@/services/referensi/jenisBelanja-service'
import { useFormik } from 'formik'
import { Button } from 'primereact/button'
import { Dialog } from 'primereact/dialog'
import { InputText } from 'primereact/inputtext'
export default function FormJenisBelanja({ dialogForm, setDialogForm, dataEdit, setDataEdit, refresh, toast }) {
const formik = useFormik({
initialValues: {
ref_id: dataEdit.jenis_id || '',
nama: dataEdit.nama || '',
},
validate: (data) => {
let errors = {}
if (!data.nama) errors.nama = 'Nama is required.'
return errors
},
onSubmit: (data) => {
if (data.ref_id) {
JenisBelanjaUpdate(data).then((res) => {
if (res.status === 'success') {
refresh(Math.random)
formik.resetForm()
setDataEdit([])
setDialogForm(false)
toast.current.show({
severity: 'success',
detail: res.message,
closable: false,
})
} else {
setDialogForm(false)
toast.current.show({
severity: 'error',
detail: res.message,
closable: false,
})
}
})
} else {
JenisBelanjaCreate(data).then((res) => {
if (res.status === 'success') {
refresh(Math.random)
formik.resetForm()
setDataEdit([])
setDialogForm(false)
toast.current.show({
severity: 'success',
detail: res.message,
closable: false,
})
} else {
setDialogForm(false)
toast.current.show({
severity: 'error',
detail: res.message,
closable: false,
})
}
})
}
},
})
const isFieldValid = (field) => !!(formik.touched[field] && formik.errors[field])
const errorFieldMessage = (field) => {
return (
isFieldValid(field) && (
<small className='p-error' style={{ fontSize: '11px' }}>
{formik.errors[field]}
</small>
)
)
}
const dialogFooter = (
<div className='flex justify-end'>
<Button
type='submit'
label='Cancel'
className='p-button-sm p-button-secondary'
onClick={() => {
formik.resetForm()
setDialogForm(false)
}}
/>
<Button type='submit' label='Save' className='p-button-sm p-button-primary' onClick={formik.handleSubmit} />
</div>
)
return (
<>
<Dialog
header={formik.values.ref_id ? 'Update Jenis Belanja' : 'Add Jenis Belanja'}
className='p-dialog-form'
visible={dialogForm}
draggable={false}
resizable={false}
position={'center'}
closable={false}
style={{ width: '30vw' }}
footer={dialogFooter}
>
<form onSubmit={formik.handleSubmit}>
<div className='p-fluid grid'>
<div className='field col-12 md:col-12 mb-0'>
<label className='block'>Nama</label>
<InputText
className='p-inputtext-sm'
name='nama'
value={formik.values.nama}
onChange={formik.handleChange}
placeholder='Masukkan nama jenis belanja'
/>
{errorFieldMessage('nama')}
</div>
</div>
</form>
</Dialog>
</>
)
}
+149
View File
@@ -0,0 +1,149 @@
import { JenisBelanjaList } from '@/services/referensi/jenisBelanja-service'
import { JenisKegiatanCreate, JenisKegiatanUpdate } from '@/services/referensi/jenisKegiatan-service'
import { useFormik } from 'formik'
import { Button } from 'primereact/button'
import { Dialog } from 'primereact/dialog'
import { Dropdown } from 'primereact/dropdown'
import { InputText } from 'primereact/inputtext'
import { useEffect, useState } from 'react'
export default function FormJenisKegiatan({ dialogForm, setDialogForm, dataEdit, setDataEdit, refresh, toast }) {
const [optionJenisBelanja, setOptionJenisBelanja] = useState([])
useEffect(() => {
JenisBelanjaList({ draw: 0 }).then((res) => setOptionJenisBelanja(res.data))
}, [])
const formik = useFormik({
initialValues: {
ref_id: dataEdit.jenis_id || '',
nama: dataEdit.nama || '',
jenis_belanja_id: dataEdit.jenis_belanja_id || '',
},
validate: (data) => {
let errors = {}
if (!data.nama) errors.nama = 'Nama is required.'
if (!data.jenis_belanja_id) errors.jenis_belanja_id = 'Jenis Belanja is required.'
return errors
},
onSubmit: (data) => {
if (data.ref_id) {
JenisKegiatanUpdate(data).then((res) => {
if (res.status === 'success') {
refresh(Math.random)
formik.resetForm()
setDataEdit([])
setDialogForm(false)
toast.current.show({
severity: 'success',
detail: res.message,
closable: false,
})
} else {
setDialogForm(false)
toast.current.show({
severity: 'error',
detail: res.message,
closable: false,
})
}
})
} else {
JenisKegiatanCreate(data).then((res) => {
if (res.status === 'success') {
refresh(Math.random)
formik.resetForm()
setDataEdit([])
setDialogForm(false)
toast.current.show({
severity: 'success',
detail: res.message,
closable: false,
})
} else {
setDialogForm(false)
toast.current.show({
severity: 'error',
detail: res.message,
closable: false,
})
}
})
}
},
})
const isFieldValid = (field) => !!(formik.touched[field] && formik.errors[field])
const errorFieldMessage = (field) => {
return (
isFieldValid(field) && (
<small className='p-error' style={{ fontSize: '11px' }}>
{formik.errors[field]}
</small>
)
)
}
const dialogFooter = (
<div className='flex justify-end'>
<Button
type='submit'
label='Cancel'
className='p-button-sm p-button-secondary'
onClick={() => {
formik.resetForm()
setDialogForm(false)
}}
/>
<Button type='submit' label='Save' className='p-button-sm p-button-primary' onClick={formik.handleSubmit} />
</div>
)
return (
<>
<Dialog
header={formik.values.ref_id ? 'Update Jenis Kegiatan' : 'Add Jenis Kegiatan'}
className='p-dialog-form'
visible={dialogForm}
draggable={false}
resizable={false}
position={'center'}
closable={false}
style={{ width: '30vw' }}
footer={dialogFooter}
>
<form onSubmit={formik.handleSubmit}>
<div className='p-fluid grid gap-y-3'>
<div className='field col-12 md:col-12'>
<label className='block'>Nama</label>
<InputText
className='p-inputtext-sm'
name='nama'
value={formik.values.nama}
onChange={formik.handleChange}
placeholder='Masukkan nama jenis kegiatan'
/>
{errorFieldMessage('nama')}
</div>
<div className='field col-12 md:col-4'>
<label className='block'>Jenis Belanja</label>
<Dropdown
panelClassName='p-dropdown-form'
name='jenis_belanja_id'
options={optionJenisBelanja}
optionLabel='nama'
optionValue='jenis_id'
value={formik.values.jenis_belanja_id}
onChange={formik.handleChange}
showClear={formik.values.jenis_belanja_id ? true : false}
scrollHeight='200px'
placeholder='Select Jenis Belanja'
/>
{errorFieldMessage('jenis_belanja_id')}
</div>
</div>
</form>
</Dialog>
</>
)
}
+122
View File
@@ -0,0 +1,122 @@
import { JenisTagihanCreate, JenisTagihanUpdate } from '@/services/referensi/jenisTagihan-service'
import { useFormik } from 'formik'
import { Button } from 'primereact/button'
import { Dialog } from 'primereact/dialog'
import { InputText } from 'primereact/inputtext'
export default function FormJenisTagihan({ dialogForm, setDialogForm, dataEdit, setDataEdit, refresh, toast }) {
const formik = useFormik({
initialValues: {
ref_id: dataEdit.jenis_id || '',
nama: dataEdit.nama || '',
},
validate: (data) => {
let errors = {}
if (!data.nama) errors.nama = 'Nama is required.'
return errors
},
onSubmit: (data) => {
if (data.ref_id) {
JenisTagihanUpdate(data).then((res) => {
if (res.status === 'success') {
refresh(Math.random)
formik.resetForm()
setDataEdit([])
setDialogForm(false)
toast.current.show({
severity: 'success',
detail: res.message,
closable: false,
})
} else {
setDialogForm(false)
toast.current.show({
severity: 'error',
detail: res.message,
closable: false,
})
}
})
} else {
JenisTagihanCreate(data).then((res) => {
if (res.status === 'success') {
refresh(Math.random)
formik.resetForm()
setDataEdit([])
setDialogForm(false)
toast.current.show({
severity: 'success',
detail: res.message,
closable: false,
})
} else {
setDialogForm(false)
toast.current.show({
severity: 'error',
detail: res.message,
closable: false,
})
}
})
}
},
})
const isFieldValid = (field) => !!(formik.touched[field] && formik.errors[field])
const errorFieldMessage = (field) => {
return (
isFieldValid(field) && (
<small className='p-error' style={{ fontSize: '11px' }}>
{formik.errors[field]}
</small>
)
)
}
const dialogFooter = (
<div className='flex justify-end'>
<Button
type='submit'
label='Cancel'
className='p-button-sm p-button-secondary'
onClick={() => {
formik.resetForm()
setDialogForm(false)
}}
/>
<Button type='submit' label='Save' className='p-button-sm p-button-primary' onClick={formik.handleSubmit} />
</div>
)
return (
<>
<Dialog
header={formik.values.ref_id ? 'Update Jenis Tagihan' : 'Add Jenis Tagihan'}
className='p-dialog-form'
visible={dialogForm}
draggable={false}
resizable={false}
position={'center'}
closable={false}
style={{ width: '30vw' }}
footer={dialogFooter}
>
<form onSubmit={formik.handleSubmit}>
<div className='p-fluid grid'>
<div className='field col-12 md:col-12 mb-0'>
<label className='block'>Nama</label>
<InputText
className='p-inputtext-sm'
name='nama'
value={formik.values.nama}
onChange={formik.handleChange}
placeholder='Masukkan nama jenis tagihan'
/>
{errorFieldMessage('nama')}
</div>
</div>
</form>
</Dialog>
</>
)
}
+236
View File
@@ -0,0 +1,236 @@
import { JenisBelanjaList } from '@/services/referensi/jenisBelanja-service'
import { JenisKegiatanList } from '@/services/referensi/jenisKegiatan-service'
import { JenisTagihanList } from '@/services/referensi/jenisTagihan-service'
import { PersyaratanCreate, PersyaratanUpdate } from '@/services/referensi/persyaratan-service'
import { FieldArray, Formik } from 'formik'
import { Button } from 'primereact/button'
import { Dialog } from 'primereact/dialog'
import { Dropdown } from 'primereact/dropdown'
import { InputText } from 'primereact/inputtext'
import { InputTextarea } from 'primereact/inputtextarea'
import { useEffect, useState } from 'react'
export default function FormPersyaratan({ dialogForm, setDialogForm, dataEdit, setDataEdit, refresh, toast }) {
const [optionJenisTagihan, setOptionJenisTagihan] = useState([])
const [optionJenisBelanja, setOptionJenisBelanja] = useState([])
const [optionJenisKegiatan, setOptionJenisKegiatan] = useState([])
useEffect(() => {
JenisTagihanList({ draw: 0 }).then((res) => setOptionJenisTagihan(res.data))
JenisBelanjaList({ draw: 0 }).then((res) => setOptionJenisBelanja(res.data))
JenisKegiatanList({ draw: 0 }).then((res) => setOptionJenisKegiatan(res.data))
}, [])
return (
<>
<Formik
initialValues={{
syarat_id: dataEdit.syarat_id || '',
jenis_tagihan: dataEdit.jenis_tagihan_id || '',
jenis_belanja: dataEdit.jenis_belanja_id || '',
jenis_kegiatan: dataEdit.jenis_kegiatan_id || '',
syarat: [{}],
}}
validate={(data) => {
let errors = {}
if (!data.jenis_tagihan) errors.jenis_tagihan = 'Jenis Tagihan is required.'
if (!data.jenis_belanja) errors.jenis_belanja = 'Jenis Belanja is required.'
if (!data.jenis_kegiatan) errors.jenis_kegiatan = 'Jenis Kegiatan is required.'
// if (!data.syarat) errors.syarat = 'Syarat Dokumen is required.'
// if (!data.keterangan) errors.keterangan = 'Keterangan is required.'
return errors
}}
onSubmit={(data) => {
if (data.syarat_id) {
PersyaratanUpdate(data).then((res) => {
if (res.status === 'success') {
refresh(Math.random)
setDataEdit([])
setDialogForm(false)
toast.current.show({
severity: 'success',
detail: res.message,
closable: false,
})
} else {
setDialogForm(false)
toast.current.show({
severity: 'error',
detail: res.message,
closable: false,
})
}
})
} else {
PersyaratanCreate(data).then((res) => {
if (res.status === 'success') {
refresh(Math.random)
setDataEdit([])
setDialogForm(false)
toast.current.show({
severity: 'success',
detail: res.message,
closable: false,
})
} else {
setDialogForm(false)
toast.current.show({
severity: 'error',
detail: res.message,
closable: false,
})
}
})
}
}}
validateOnChange={false}
>
{({ values, errors, handleChange, handleSubmit, isSubmitting, resetForm }) => {
const dialogFooter = (
<div className='flex justify-end'>
<Button
type='submit'
label='Cancel'
className='p-button-sm p-button-secondary'
onClick={() => {
resetForm()
setDialogForm(false)
}}
/>
<Button
type='submit'
label='Save'
className='p-button-sm p-button-primary'
onClick={handleSubmit}
loading={isSubmitting}
/>
</div>
)
return (
<Dialog
header={values.syarat_id ? 'Update Persyaratan' : 'Add Persyaratan'}
className='p-dialog-form'
visible={dialogForm}
draggable={false}
resizable={false}
position={'center'}
closable={false}
style={{ width: '45vw' }}
footer={dialogFooter}
>
<form onSubmit={handleSubmit}>
<div className='p-fluid grid gap-y-2'>
<div className='field col-12 md:col-4'>
<label className='block'>Jenis Tagihan</label>
<Dropdown
panelClassName='p-dropdown-form'
name='jenis_tagihan'
options={optionJenisTagihan}
optionLabel='nama'
optionValue='jenis_id'
value={values.jenis_tagihan}
onChange={handleChange}
showClear={values.jenis_tagihan ? true : false}
scrollHeight='200px'
placeholder='Select Jenis Tagihan'
/>
{errors.jenis_tagihan && <div className='text-red-500 text-xs'>{errors.jenis_tagihan}</div>}
</div>
<div className='field col-12 md:col-4'>
<label className='block'>Jenis Belanja</label>
<Dropdown
panelClassName='p-dropdown-form'
name='jenis_belanja'
options={optionJenisBelanja}
optionLabel='nama'
optionValue='jenis_id'
value={values.jenis_belanja}
onChange={handleChange}
showClear={values.jenis_belanja ? true : false}
scrollHeight='200px'
placeholder='Select Jenis Belanja'
/>
{errors.jenis_belanja && <div className='text-red-500 text-xs'>{errors.jenis_belanja}</div>}
</div>
<div className='field col-12 md:col-4'>
<label className='block'>Jenis Kegiatan</label>
<Dropdown
panelClassName='p-dropdown-form'
name='jenis_kegiatan'
options={optionJenisKegiatan}
optionLabel='nama'
optionValue='jenis_id'
value={values.jenis_kegiatan}
onChange={handleChange}
showClear={values.jenis_kegiatan ? true : false}
scrollHeight='200px'
placeholder='Select Jenis Kegiatan'
/>
{errors.jenis_kegiatan && <div className='text-red-500 text-xs'>{errors.jenis_kegiatan}</div>}
</div>
<FieldArray
name='syarat'
render={(arrayHelpers) => (
<div className=''>
<label className='block'>Syarat</label>
<div className='flex flex-col gap-1'>
{values.syarat.map((syarat, index) => (
<div key={index} className='field col-12 flex gap-2 items-center'>
<div className='border p-3 rounded shadow my-2 w-full flex flex-col gap-2'>
<div className='flex flex-col gap-1'>
<label className='block'>Nama Syarat {index + 1}</label>
<InputText
className='p-inputtext-sm'
name={`syarat.${index}.syarat`}
value={values.syarat[index].syarat}
onChange={handleChange}
placeholder='Masukkan Syarat Dokumen'
/>
{errors.syarat && errors.syarat[index] && (
<div className='text-red-500 text-xs'>{errors.syarat[index].syarat}</div>
)}
</div>
<div className='flex flex-col gap-1'>
<label className='block'>Keterangan Syarat {index + 1}</label>
<InputTextarea
name={`syarat.${index}.keterangan`}
rows={3}
cols={30}
value={values.syarat[index].keterangan}
onChange={handleChange}
placeholder='Masukkan Keterangan'
/>
</div>
</div>
{index > 0 && (
<Button
icon='pi pi-times'
className='p-button-danger p-button-sm'
onClick={() => arrayHelpers.remove(index)}
/>
)}
</div>
))}
<div className='w-fit relative left-1/2 -translate-x-1/2'>
<Button
type='button'
icon='pi pi-plus'
className='p-button-sm'
label='Tambah Syarat'
onClick={() => arrayHelpers.push({ syarat: '', keterangan: '' })}
/>
</div>
</div>
</div>
)}
/>
</div>
</form>
</Dialog>
)
}}
</Formik>
</>
)
}
+220
View File
@@ -0,0 +1,220 @@
import { RoleCreate, RoleUpdate } from '@/services/manajemen/role-service'
import { useFormik } from 'formik'
import { Button } from 'primereact/button'
import { Dialog } from 'primereact/dialog'
import { InputText } from 'primereact/inputtext'
import { Tree } from 'primereact/tree'
export default function FormRole({ dialogForm, setDialogForm, dataEdit, setDataEdit, refresh, toast }) {
const formik = useFormik({
initialValues: {
role_id: dataEdit.role_id || '',
nama: dataEdit.nama || '',
access: dataEdit.access || [],
},
validate: (data) => {
let errors = {}
if (!data.nama) errors.nama = 'Nama is required.'
if (!data.access) errors.access = 'Nama is required.'
return errors
},
onSubmit: (data) => {
Object.assign(data, { access: JSON.stringify(data.access) })
if (data.role_id) {
RoleUpdate(data).then((res) => {
if (res.status === 'success') {
refresh(Math.random)
formik.resetForm()
setDataEdit([])
setDialogForm(false)
toast.current.show({
severity: 'success',
detail: res.message,
closable: false,
})
} else {
setDialogForm(false)
toast.current.show({
severity: 'error',
detail: res.message,
closable: false,
})
}
})
} else {
RoleCreate(data).then((res) => {
if (res.status === 'success') {
refresh(Math.random)
formik.resetForm()
setDataEdit([])
setDialogForm(false)
toast.current.show({
severity: 'success',
detail: res.message,
closable: false,
})
} else {
setDialogForm(false)
toast.current.show({
severity: 'error',
detail: res.message,
closable: false,
})
}
})
}
},
})
const isFieldValid = (field) => !!(formik.touched[field] && formik.errors[field])
const errorFieldMessage = (field) => {
return (
isFieldValid(field) && (
<small className='p-error' style={{ fontSize: '11px' }}>
{formik.errors[field]}
</small>
)
)
}
const dialogFooter = (
<div className='flex justify-end'>
<Button
type='submit'
label='Cancel'
className='p-button-sm p-button-secondary'
onClick={() => {
formik.resetForm()
setDialogForm(false)
}}
/>
<Button type='submit' label='Save' className='p-button-sm p-button-primary' onClick={formik.handleSubmit} />
</div>
)
const data = [
{
key: 'dashboard',
label: 'Dashboard',
icon: 'pi pi-fw pi-home',
},
{
key: 'referensi',
label: 'Referensi',
icon: 'pi pi-fw pi-database',
children: [
{ key: 'referensi/jenis-tagihan', label: 'Jenis Tagihan' },
{ key: 'referensi/jenis-belanja', label: 'Jenis Belanja' },
{ key: 'referensi/jenis-kegiatan', label: 'Jenis Kegiatan' },
{ key: 'referensi/akun', label: 'Akun' },
{ key: 'referensi/persyaratan', label: 'Persyaratan' },
{ key: 'referensi/unit-kerja', label: 'Unit Kerja' },
{ key: 'referensi/verifikator', label: 'Verifikator' },
],
},
{
key: 'pengajuan-tagihan',
label: 'Pengajuan Tagihan',
icon: 'pi pi-fw pi-dollar',
},
{
key: 'laporan',
label: 'Laporan',
icon: 'pi pi-fw pi-chart-line',
children: [
{ key: 'laporan/per-user', label: 'Per User (Verifikator, kasub verif)' },
// { key: 'laporan/approval', label: 'Approval (Kabag verif, bendahara, ppspm)' },
{ key: 'laporan/rekap-bulanan-per-user', label: 'Rekapitulasi bulanan per user' },
{ key: 'laporan/rekap-verif-per-bulan', label: 'Rekapitulasi hasil verifikasi per bulan' },
{ key: 'laporan/rekap-per-unit-kerja', label: 'Rekapitulasi per unit kerja' },
{ key: 'laporan/rekap-per-jenis-belanja', label: 'Rekapitulasi per jenis belanja (BAS)' },
{ key: 'laporan/verif-per-bulan', label: 'Hasil verifikasi per bulan (detail)' },
{
key: 'laporan/pengendalian-waktu-penyelesaian',
label: 'Pengendalian waktu penyelesaian tagihan per unit per bulan',
},
{
key: 'laporan/pengendalian-waktu-penyelesaian-detail',
label: 'Pengendalian waktu penyelesaian tagihan per unit per bulan (detail)',
},
],
},
{
key: 'otorisasi',
label: 'Otorisasi',
icon: 'pi pi-fw pi-lock',
children: [
{ key: 'otorisasi/verifikasi', label: 'verifikasi' },
{ key: 'otorisasi/rekomendasi', label: 'rekomendasi' },
{ key: 'otorisasi/persetujuan', label: 'persetujuan' },
{ key: 'otorisasi/pengesahan', label: 'pengesahan' },
{ key: 'otorisasi/spm', label: 'spm' },
],
},
{
key: 'manajemen',
label: 'Manajemen',
icon: 'pi pi-fw pi-database',
children: [
{ key: 'manajemen/user', label: 'user' },
{ key: 'manajemen/role', label: 'role' },
{ key: 'manajemen/jam-kerja', label: 'jam kerja' },
],
},
]
return (
<>
<Dialog
header={formik.values.role_id ? 'Update Role' : 'Add Role'}
className='p-dialog-form'
visible={dialogForm}
draggable={false}
resizable={false}
position={'center'}
closable={false}
style={{ width: '60vw' }}
footer={dialogFooter}
>
<form onSubmit={formik.handleSubmit}>
<div className='grid grid-cols-2 gap-x-3'>
{/* KIRI */}
<div className='kiri'>
<div className='p-fluid grid'>
<div className='field col-12 md:col-12 mb-0'>
<label className='block'>List menu</label>
<Tree
name='access'
value={data}
selectionMode='checkbox'
selectionKeys={formik.values.access}
onSelectionChange={(e) => {
formik.setFieldValue('access', e.value)
}}
/>
</div>
</div>
</div>
{/* KANAN */}
<div className='kanan'>
<div className='p-fluid grid'>
<div className='field col-12 md:col-12 mb-0'>
<label className='block'>Nama Role</label>
<InputText
className='p-inputtext-sm'
name='nama'
value={formik.values.nama}
onChange={formik.handleChange}
placeholder='Masukkan nama role'
/>
{errorFieldMessage('nama')}
</div>
</div>
</div>
</div>
</form>
</Dialog>
</>
)
}
+122
View File
@@ -0,0 +1,122 @@
import { TagihanCreate, TagihanUpdate } from '@/services/pengajuan-tagihan/tagihan-service'
import { useFormik } from 'formik'
import { Button } from 'primereact/button'
import { Dialog } from 'primereact/dialog'
import { InputText } from 'primereact/inputtext'
export default function FormTagihan({ dialogForm, setDialogForm, dataEdit, setDataEdit, refresh, toast }) {
const formik = useFormik({
initialValues: {
ref_id: dataEdit.ref_id || '',
nama: dataEdit.nama || '',
},
validate: (data) => {
let errors = {}
if (!data.nama) errors.nama = 'Nama is required.'
return errors
},
onSubmit: (data) => {
if (data.ref_id) {
TagihanUpdate(data).then((res) => {
if (res.status === 'success') {
refresh(Math.random)
formik.resetForm()
setDataEdit([])
setDialogForm(false)
toast.current.show({
severity: 'success',
detail: res.message,
closable: false,
})
} else {
setDialogForm(false)
toast.current.show({
severity: 'error',
detail: res.message,
closable: false,
})
}
})
} else {
TagihanCreate(data).then((res) => {
if (res.status === 'success') {
refresh(Math.random)
formik.resetForm()
setDataEdit([])
setDialogForm(false)
toast.current.show({
severity: 'success',
detail: res.message,
closable: false,
})
} else {
setDialogForm(false)
toast.current.show({
severity: 'error',
detail: res.message,
closable: false,
})
}
})
}
},
})
const isFieldValid = (field) => !!(formik.touched[field] && formik.errors[field])
const errorFieldMessage = (field) => {
return (
isFieldValid(field) && (
<small className='p-error' style={{ fontSize: '11px' }}>
{formik.errors[field]}
</small>
)
)
}
const dialogFooter = (
<div className='flex justify-end'>
<Button
type='submit'
label='Cancel'
className='p-button-sm p-button-secondary'
onClick={() => {
formik.resetForm()
setDialogForm(false)
}}
/>
<Button type='submit' label='Save' className='p-button-sm p-button-primary' onClick={formik.handleSubmit} />
</div>
)
return (
<>
<Dialog
header={formik.values.ref_id ? 'Update Tagihan' : 'Add Tagihan'}
className='p-dialog-form'
visible={dialogForm}
draggable={false}
resizable={false}
position={'center'}
closable={false}
style={{ width: '30vw' }}
footer={dialogFooter}
>
<form onSubmit={formik.handleSubmit}>
<div className='p-fluid grid'>
<div className='field col-12 md:col-12 mb-0'>
<label className='block'>Nama</label>
<InputText
className='p-inputtext-sm'
name='nama'
value={formik.values.nama}
onChange={formik.handleChange}
placeholder='Masukkan nama jenis tagihan'
/>
{errorFieldMessage('nama')}
</div>
</div>
</form>
</Dialog>
</>
)
}
+148
View File
@@ -0,0 +1,148 @@
import { UnitKerjaCreate, UnitKerjaUpdate } from '@/services/referensi/unitKerja-service'
import { useFormik } from 'formik'
import { Button } from 'primereact/button'
import { Dialog } from 'primereact/dialog'
import { InputText } from 'primereact/inputtext'
export default function FormUnitKerja({ dialogForm, setDialogForm, dataEdit, setDataEdit, refresh, toast }) {
const formik = useFormik({
initialValues: {
ref_id: dataEdit.ref_id || '',
unit_id: dataEdit.unit_id || '',
nama: dataEdit.nama || '',
bobot: dataEdit.bobot || '',
},
validate: (data) => {
let errors = {}
if (!data.unit_id) errors.unit_id = 'Kode Unit is required.'
if (!data.nama) errors.nama = 'Nama is required.'
if (!data.bobot) errors.bobot = 'Bobot is required.'
return errors
},
onSubmit: (data) => {
if (data.ref_id) {
UnitKerjaUpdate(data).then((res) => {
if (res.status === 'success') {
refresh(Math.random)
formik.resetForm()
setDataEdit([])
setDialogForm(false)
toast.current.show({
severity: 'success',
detail: res.message,
closable: false,
})
} else {
setDialogForm(false)
toast.current.show({
severity: 'error',
detail: res.message,
closable: false,
})
}
})
} else {
UnitKerjaCreate(data).then((res) => {
if (res.status === 'success') {
refresh(Math.random)
formik.resetForm()
setDataEdit([])
setDialogForm(false)
toast.current.show({
severity: 'success',
detail: res.message,
closable: false,
})
} else {
setDialogForm(false)
toast.current.show({
severity: 'error',
detail: res.message,
closable: false,
})
}
})
}
},
})
const isFieldValid = (field) => !!(formik.errors[field] && formik.touched[field])
const errorFieldMessage = (field) => {
return (
isFieldValid(field) && (
<small className='p-error' style={{ fontSize: '11px' }}>
{formik.errors[field]}
</small>
)
)
}
const dialogFooter = (
<div className='flex justify-end'>
<Button
type='submit'
label='Cancel'
className='p-button-sm p-button-secondary'
onClick={() => {
formik.resetForm()
setDialogForm(false)
}}
/>
<Button type='submit' label='Save' className='p-button-sm p-button-primary' onClick={formik.handleSubmit} />
</div>
)
return (
<>
<Dialog
header={formik.values.unit_id ? 'Update Jenis Tagihan' : 'Add Jenis Tagihan'}
className='p-dialog-form'
visible={dialogForm}
draggable={false}
resizable={false}
position={'center'}
closable={false}
style={{ width: '30vw' }}
footer={dialogFooter}
>
<form onSubmit={formik.handleSubmit}>
<div className='p-fluid grid gap-y-3'>
<div className='field col-12 md:col-12'>
<label className='block'>Kode Unit</label>
<InputText
className='p-inputtext-sm'
name='unit_id'
value={formik.values.unit_id}
onChange={formik.handleChange}
placeholder='Masukkan Kode Unit'
/>
{errorFieldMessage('unit_id')}
</div>
<div className='field col-12 md:col-12'>
<label className='block'>Nama</label>
<InputText
className='p-inputtext-sm'
name='nama'
value={formik.values.nama}
onChange={formik.handleChange}
placeholder='Masukkan nama unit kerja'
/>
{errorFieldMessage('nama')}
</div>
<div className='field col-12 md:col-12'>
<label className='block'>Bobot</label>
<InputText
className='p-inputtext-sm'
name='bobot'
value={formik.values.bobot}
onChange={formik.handleChange}
placeholder='Masukkan bobot'
/>
{errorFieldMessage('bobot')}
</div>
</div>
</form>
</Dialog>
</>
)
}
+267
View File
@@ -0,0 +1,267 @@
import { RoleList } from '@/services/manajemen/role-service'
import { UserCreate, UserUpdate } from '@/services/manajemen/user-service'
import { UnitKerjaList } from '@/services/referensi/unitKerja-service'
import { useFormik } from 'formik'
import { Button } from 'primereact/button'
import { Dialog } from 'primereact/dialog'
import { Dropdown } from 'primereact/dropdown'
import { InputText } from 'primereact/inputtext'
import { Password } from 'primereact/password'
import { useEffect, useState } from 'react'
import * as Yup from 'yup'
export default function FormUser({ dialogForm, setDialogForm, dataEdit, setDataEdit, refresh, toast }) {
const [optionUnitKerja, setOptionUnitKerja] = useState([])
const [optionRole, setOptionRole] = useState([])
const [showUnitKerja, setShowUnitKerja] = useState(true)
const SignupSchema = Yup.object().shape({
name: Yup.string().min(2, 'Too Short!').max(50, 'Too Long!').required('Nama is required'),
username: Yup.string().min(2, 'Too Short!').max(50, 'Too Long!').required('Username is required'),
email: Yup.string().email('Invalid email').required('Email is Required'),
password: Yup.string().when('old_password', {
is: true,
then: Yup.string()
.required('Password is required')
.matches(
/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#%&])(?=.{8,})/,
'Must Contain 8 Characters, One Uppercase, One Lowercase, One Number and One Special Case Character'
),
}),
password_retype: Yup.string().when('old_password', {
is: true,
then: Yup.string()
.oneOf([Yup.ref('password'), null], 'Passwords must match')
.required('Password confirm is required'),
}),
// unit: Yup.string().required('Unit kerja is required'),
role: Yup.string().required('Role is required'),
})
const formik = useFormik({
initialValues: {
user_id: dataEdit.user_id || '',
name: dataEdit.nama || '',
username: dataEdit.username || '',
email: dataEdit.email || '',
password: '',
password_retype: '',
unit: dataEdit.unit || '',
role: dataEdit.user_role || '',
},
validationSchema: SignupSchema,
onSubmit: (data) => {
if (data.user_id) {
UserUpdate(data).then((res) => {
if (res.status === 'success') {
refresh(Math.random)
formik.resetForm()
setDataEdit([])
setDialogForm(false)
toast.current.show({
severity: 'success',
detail: res.message,
closable: false,
})
} else {
setDialogForm(false)
toast.current.show({
severity: 'error',
detail: res.message,
closable: false,
})
}
})
} else {
UserCreate(data).then((res) => {
if (res.status === 'success') {
refresh(Math.random)
formik.resetForm()
setDataEdit([])
setDialogForm(false)
toast.current.show({
severity: 'success',
detail: res.message,
closable: false,
})
} else {
setDialogForm(false)
toast.current.show({
severity: 'error',
detail: res.message,
closable: false,
})
}
})
}
},
})
useEffect(() => {
UnitKerjaList({ draw: 0 }).then((res) => setOptionUnitKerja(res.data))
RoleList().then((res) => setOptionRole(res.data))
}, [])
const isFieldValid = (field) => !!(formik.touched[field] && formik.errors[field])
const errorFieldMessage = (field) => {
return (
isFieldValid(field) && (
<small className='p-error' style={{ fontSize: '11px' }}>
{formik.errors[field]}
</small>
)
)
}
const dialogFooter = (
<div className='flex justify-end'>
<Button
type='submit'
label='Cancel'
className='p-button-sm p-button-secondary'
onClick={() => {
formik.resetForm()
setDialogForm(false)
}}
/>
<Button type='submit' label='Save' className='p-button-sm p-button-primary' onClick={formik.handleSubmit} />
</div>
)
const header = <h6>Pick a password</h6>
const footer = (
<>
<p className='mt-3'>Suggestions</p>
<ul className='pl-2 ml-2 mt-0' style={{ lineHeight: '1.5' }}>
<li>At least one lowercase</li>
<li>At least one uppercase</li>
<li>At least one numeric</li>
<li>At least one special case character</li>
<li>Minimum 8 characters</li>
<li>If edit password not required</li>
</ul>
</>
)
const handleRole = (e) => {
if (e.target.value === 'ROL-a713f345-9b9a-453a-8f77-33fd8335078f') {
setShowUnitKerja(false)
} else {
setShowUnitKerja(true)
}
formik.setFieldValue('role', e.target.value)
}
return (
<>
<Dialog
header={formik.values.user_id ? 'Update User' : 'Add User'}
className='p-dialog-form'
visible={dialogForm}
draggable={false}
resizable={false}
position={'center'}
closable={false}
style={{ width: '30vw' }}
footer={dialogFooter}
>
<form onSubmit={formik.handleSubmit}>
<div className='kanan'>
<div className='p-fluid grid'>
<div className='field col-12 md:col-12 mb-2'>
<label className='block'>Nama</label>
<InputText
className='p-inputtext-sm'
name='name'
value={formik.values.name}
onChange={formik.handleChange}
placeholder='Masukkan nama'
/>
{errorFieldMessage('name')}
</div>
<div className='field col-12 md:col-12 mb-2'>
<label className='block'>Email</label>
<InputText
className='p-inputtext-sm'
name='email'
value={formik.values.email}
onChange={formik.handleChange}
placeholder='Masukkan email'
/>
{errorFieldMessage('email')}
</div>
<div className='field col-12 md:col-12 mb-2'>
<label className='block'>Username</label>
<InputText
className='p-inputtext-sm'
name='username'
value={formik.values.username}
onChange={formik.handleChange}
placeholder='Masukkan username'
/>
{errorFieldMessage('username')}
</div>
<div className='field col-12 md:col-12 mb-2'>
<label className='block'>Password</label>
<Password
name='password'
value={formik.values.password}
onChange={formik.handleChange}
header={header}
footer={footer}
toggleMask
/>
{errorFieldMessage('password')}
</div>
<div className='field col-12 md:col-12 mb-2'>
<label className='block'>Password Confirm</label>
<Password
name='password_retype'
value={formik.values.password_retype}
onChange={formik.handleChange}
feedback={false}
toggleMask
/>
{errorFieldMessage('password_retype')}
</div>
<div className='field col-12 md:col-4'>
<label className='block'>Role</label>
<Dropdown
panelClassName='p-dropdown-form'
name='role'
options={optionRole}
optionLabel='nama'
optionValue='role_id'
value={formik.values.role}
onChange={(e) => handleRole(e)}
showClear={formik.values.role ? true : false}
scrollHeight='200px'
placeholder='Select role'
/>
{errorFieldMessage('role')}
</div>
<div className='field col-12 md:col-4'>
<label className='block'>Unit Kerja</label>
<Dropdown
panelClassName='p-dropdown-form'
name='unit'
options={optionUnitKerja}
optionLabel='nama'
optionValue='unit_id'
value={formik.values.unit}
onChange={formik.handleChange}
showClear={formik.values.unit ? true : false}
scrollHeight='200px'
placeholder='Select unit kerja'
disabled={showUnitKerja}
/>
{errorFieldMessage('unit')}
</div>
</div>
</div>
</form>
</Dialog>
</>
)
}
+79
View File
@@ -0,0 +1,79 @@
import { useFormik } from 'formik'
import { Button } from 'primereact/button'
import { Dialog } from 'primereact/dialog'
import { InputText } from 'primereact/inputtext'
export default function FormVerifikasi({ dialogForm, setDialogForm, dataEdit }) {
const formik = useFormik({
initialValues: {
ref_id: dataEdit.ref_id || '',
nama: dataEdit.nama || '',
},
validate: (data) => {
let errors = {}
if (!data.nama) errors.nama = 'Nama is required.'
return errors
},
onSubmit: (data) => {
console.log(data)
},
})
const isFieldValid = (field) => !!(formik.touched[field] && formik.errors[field])
const errorFieldMessage = (field) => {
return (
isFieldValid(field) && (
<small className='p-error' style={{ fontSize: '11px' }}>
{formik.errors[field]}
</small>
)
)
}
const dialogFooter = (
<div className='flex justify-end'>
<Button
type='submit'
label='Cancel'
className='p-button-sm p-button-secondary'
onClick={() => {
formik.resetForm()
setDialogForm(false)
}}
/>
<Button type='submit' label='Save' className='p-button-sm p-button-primary' onClick={formik.handleSubmit} />
</div>
)
return (
<>
<Dialog
header={formik.values.ref_id ? 'Update Verifikasi' : 'Add Verifikasi'}
className='p-dialog-form'
visible={dialogForm}
draggable={false}
resizable={false}
position={'center'}
closable={false}
style={{ width: '30vw' }}
footer={dialogFooter}
>
<form onSubmit={formik.handleSubmit}>
<div className='p-fluid grid'>
<div className='field col-12 md:col-12 mb-0'>
<label className='block'>Nama</label>
<InputText
className='p-inputtext-sm'
name='nama'
value={formik.values.nama}
onChange={formik.handleChange}
placeholder='Masukkan nama jenis tagihan'
/>
{errorFieldMessage('nama')}
</div>
</div>
</form>
</Dialog>
</>
)
}
+131
View File
@@ -0,0 +1,131 @@
import { UserList } from '@/services/manajemen/user-service'
import { UnitKerjaList } from '@/services/referensi/unitKerja-service'
import { VerifikatorCreate } from '@/services/referensi/verifikator-service'
import { useFormik } from 'formik'
import { Button } from 'primereact/button'
import { Dialog } from 'primereact/dialog'
import { Dropdown } from 'primereact/dropdown'
import { MultiSelect } from 'primereact/multiselect'
import { useEffect, useState } from 'react'
export default function FormVerifikator({ dialogForm, setDialogForm, dataEdit, setDataEdit, refresh, toast }) {
const [ddVerifikator, setDdVerifikator] = useState([])
const [ddUserList, setDdUserList] = useState([])
useEffect(() => {
UnitKerjaList({ draw: 0 }).then((res) => {
setDdVerifikator(res.data)
})
UserList({ draw: 0 }).then((res) => {
setDdUserList(res.data)
})
}, [])
const formik = useFormik({
initialValues: {
unit_id: '',
user_id: dataEdit.user_id || '',
},
validate: (data) => {
let errors = {}
if (!data.unit_id) errors.unit_id = 'Kode Unit is required.'
if (!data.user_id) errors.user_id = 'Nama is required.'
return errors
},
onSubmit: (data) => {
VerifikatorCreate(data).then((res) => {
if (res.status === 'success') {
refresh(Math.random)
formik.resetForm()
setDataEdit([])
setDialogForm(false)
toast.current.show({
severity: 'success',
detail: res.message,
closable: false,
})
} else {
setDialogForm(false)
toast.current.show({
severity: 'error',
detail: res.message,
closable: false,
})
}
})
},
})
const isFieldValid = (field) => !!(formik.errors[field] && formik.touched[field])
const errorFieldMessage = (field) => {
return (
isFieldValid(field) && (
<small className='p-error' style={{ fontSize: '11px' }}>
{formik.errors[field]}
</small>
)
)
}
const dialogFooter = (
<div className='flex justify-end'>
<Button
type='submit'
label='Cancel'
className='p-button-sm p-button-secondary'
onClick={() => {
formik.resetForm()
setDialogForm(false)
}}
/>
<Button type='submit' label='Save' className='p-button-sm p-button-primary' onClick={formik.handleSubmit} />
</div>
)
return (
<>
<Dialog
header={formik.values.ref_id ? 'Update Jenis Tagihan' : 'Add Jenis Tagihan'}
className='p-dialog-form'
visible={dialogForm}
draggable={false}
resizable={false}
position={'center'}
closable={false}
style={{ width: '30vw' }}
footer={dialogFooter}
>
<form onSubmit={formik.handleSubmit}>
<div className='p-fluid grid gap-y-3'>
<div className='field col-12 md:col-12'>
<label className='block'>Nama Verifikator</label>
<Dropdown
name='user_id'
optionLabel='nama'
optionValue='user_id'
value={formik.values.user_id}
options={ddUserList}
onChange={formik.handleChange}
placeholder='Select nama verifikator'
/>
{errorFieldMessage('nama')}
</div>
<div className='field col-12 md:col-12'>
<label className='block'>Unit</label>
<MultiSelect
name='unit_id'
optionLabel='nama'
optionValue='unit_id'
value={formik.values.unit_id}
options={ddVerifikator}
onChange={formik.handleChange}
placeholder='Select unit'
/>
{errorFieldMessage('unit_id')}
</div>
</div>
</form>
</Dialog>
</>
)
}