BeritaAcara_A.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. import React, { useRef, Component } from 'react';
  2. import { useReactToPrint } from "react-to-print";
  3. import { Row, Col, Button, Popover, PopoverHeader, PopoverBody, } from "reactstrap";
  4. import Head from 'next/head'
  5. import SignatureCanvas from 'react-signature-canvas'
  6. import ComponentToPrint from "./SuratBA";
  7. import ReactToPrint, { PrintContextConsumer } from 'react-to-print';
  8. import { getOneLaporan, updateLaporan } from "@/actions/pelaporan";
  9. import DatePicker from "react-datepicker";
  10. import "react-datepicker/dist/react-datepicker.css";
  11. import id from 'date-fns/locale/id';
  12. import CopyToClipboard from "react-copy-to-clipboard";
  13. import { getAutoSave } from "@/actions/autosave";
  14. import ContentEditable from 'react-contenteditable'
  15. class BeritaAcara extends Component {
  16. constructor(props) {
  17. super(props);
  18. this.state = {
  19. isEditTempat: false,
  20. tempat: "[Mohon Diisi]",
  21. isEditTanggal: false,
  22. tanggal: "",
  23. setTanggal: false,
  24. isEditNamaPeserta: false,
  25. isEditTemuanLain: false,
  26. temuanLain: [],
  27. memberatkan: [],
  28. isEditKeberatan: false,
  29. isEditMeringankan: false,
  30. meringankan: [],
  31. sanksi: "[Mohon Diisi]",
  32. isEditSanksi: false,
  33. copied: false,
  34. setmeState: true,
  35. descPelanggaran: [],
  36. };
  37. this.updateValueRekomendasi = this.updateValueRekomendasi.bind(this)
  38. }
  39. static getInitialProps = async ({ query }) => {
  40. return { query };
  41. };
  42. componentDidMount = async () => {
  43. const { query, token, dataPelanggaran } = this.props;
  44. const { id } = query;
  45. const getDataSave = await getAutoSave({ id, laporan: true });
  46. const dataSuratBA = getDataSave.data?.PenetapanSanksi?.dataSuratBA;
  47. this.setState(dataSuratBA)
  48. };
  49. componentDidUpdate = (prevProps) => {
  50. const { dataPelanggaran } = this.state;
  51. if (prevProps.dataPelanggaran != this.state.dataPelanggaran) {
  52. // this.state.descPelanggaran = dataPelanggaran?.map((e) => ({ id: e._id, simpulan: "simpulan", rekomendasi: "rekomendasi" }))
  53. const descPelanggaran = {}
  54. dataPelanggaran?.forEach(e => {
  55. descPelanggaran[e._id] = {
  56. simpulan: 'simpulan',
  57. rekomendasi: 'rekomendasi'
  58. }
  59. });
  60. // this.setState({ descPelanggaran })
  61. }
  62. }
  63. updateValueSimpulan = (evt, id) => {
  64. // this.state.descPelanggaran[id]?.simpulan = evt.target.value
  65. this.setState((prevState) => ({
  66. ...prevState, descPelanggaran: {
  67. ...prevState.descPelanggaran, [id]: {
  68. ...prevState.descPelanggaran[id], simpulan: evt.target.value
  69. }
  70. }
  71. }), this.handleAutoSave)
  72. }
  73. updateValueRekomendasi = (evt, id) => {
  74. // this.state.descPelanggaran[id]?.simpulan = evt.target.value
  75. this.setState((prevState) => ({
  76. ...prevState, descPelanggaran: {
  77. ...prevState.descPelanggaran, [id]: {
  78. ...prevState.descPelanggaran[id], rekomendasi: evt.target.value
  79. }
  80. }
  81. }), this.handleAutoSave)
  82. }
  83. setDataSuratBA = () => {
  84. this.props.setDataSuratBA(this.state);
  85. }
  86. handleAutoSave = () => {
  87. this.props.handleAutoSave()
  88. }
  89. isEditTempat = () => {
  90. this.setState({
  91. isEditTempat: !this.state.isEditTempat,
  92. }, this.setDataSuratBA, this.handleAutoSave())
  93. }
  94. isEditTanggal = () => {
  95. this.setState({
  96. isEditTanggal: !this.state.isEditTanggal,
  97. }, this.setDataSuratBA, this.handleAutoSave())
  98. }
  99. isEditTemuanLain = () => {
  100. this.setState({
  101. isEditTemuanLain: !this.state.isEditTemuanLain,
  102. }, this.setDataSuratBA, this.handleAutoSave())
  103. }
  104. isEditKeberatan = () => {
  105. this.setState({
  106. isEditKeberatan: !this.state.isEditKeberatan,
  107. }, this.setDataSuratBA, this.handleAutoSave())
  108. }
  109. isEditMeringankan = () => {
  110. this.setState({
  111. isEditMeringankan: !this.state.isEditMeringankan,
  112. }, this.setDataSuratBA, this.handleAutoSave())
  113. }
  114. isEditSanksi = () => {
  115. this.setState({
  116. isEditSanksi: !this.state.isEditSanksi,
  117. }, this.setDataSuratBA, this.handleAutoSave())
  118. }
  119. updateValueTemuanLain = () => {
  120. const addTemuanLain = this.refs.inputTemuan.value
  121. this.state.temuanLain.push(addTemuanLain)
  122. this.setDataSuratBA(this.state)
  123. this.handleAutoSave()
  124. }
  125. updateValueMemringankan = () => {
  126. const addMeringankan = this.refs.inputMeringankan.value
  127. this.state.meringankan.push(addMeringankan)
  128. this.setDataSuratBA(this.state)
  129. this.handleAutoSave()
  130. }
  131. updateValueMemberatkan = () => {
  132. const addKeberatan = this.refs.inputMemberatkan.value
  133. this.state.memberatkan.push(addKeberatan)
  134. this.setDataSuratBA(this.state)
  135. this.handleAutoSave()
  136. }
  137. Copied = () => this.setState({
  138. copied: !this.state.copied
  139. })
  140. CloseCopied = () => {
  141. setTimeout(() => {
  142. this.setState({
  143. copied: !this.state.copied
  144. });
  145. }, 1000);
  146. }
  147. render() {
  148. const { dataLaporan, dataSuratBA, dataPelanggaran } = this.props
  149. const { descPelanggaran, tanggal, setTanggal } = this.state
  150. return (
  151. <div>
  152. <div className=' content-heading border-radius-login'>
  153. <span className="btn-radius">
  154. <ReactToPrint
  155. trigger={() => {
  156. return <span>
  157. <Button color className="btn-labeled-4">
  158. <h4 className="p-0 mt-2">Print dan Download</h4>
  159. </Button>
  160. </span>
  161. }}
  162. content={() => this.componentRef}
  163. />
  164. </span>
  165. </div>
  166. <div style={{ display: "none" }}>
  167. <ComponentToPrint ref={el => (this.componentRef = el)} query={this.props.query} dataPelanggaran={this.props.dataPelanggaran} dataSuratBA={this.props.dataSuratBA} />
  168. </div>
  169. <div className='page'>
  170. <page>
  171. <div className='BA-logo'>
  172. <img className='BA-logo' src="/static/img/logo-single-1-login.png" alt="logo" />
  173. </div>
  174. <h3 className='BA-header'>LAPORAN HASIL EVALUASI DAN PEMBAHASAN</h3>
  175. {dataLaporan.data && (<h3 className='BA-header'>{dataLaporan.data.pt.nama}</h3>)}
  176. <div className='body'>
  177. <p className='body'>
  178. Pada hari ini
  179. {dataSuratBA?.isEditTanggal &&
  180. <span>
  181. <DatePicker
  182. selected={tanggal ? new Date(tanggal) : tanggal}
  183. onChange={(tanggal) => {
  184. this.setState({ tanggal, setTanggal: true }, this.setDataSuratBA)
  185. }}
  186. dateFormat="dd/MM/yyyy"
  187. placeholderText="Isi Tanggal"
  188. locale={id}
  189. className="form-control bg-white"
  190. />
  191. <button className='bg-transparent button-transparent border-0 fas fa-times-circle text-danger' onClick={this.isEditTanggal} />
  192. <button className='bg-transparent button-transparent border-0 fas fa-check-circle text-success' onClick={this.isEditTanggal}
  193. />
  194. </span>
  195. }
  196. {setTanggal === true || this.state?.setTanggal === true ?
  197. <span onClick={this.isEditTanggal}> {moment(tanggal || this.state?.tanggal).locale("id").format("dddd")}, tanggal&nbsp;{moment(tanggal || this.state?.tanggal).format("D")}&nbsp; bulan &nbsp;{moment(tanggal || this.state?.tanggal).format("MMMM")} tahun &nbsp;{moment(tanggal || this.state?.tanggal).format("YYYY")},</span> :
  198. <span onClick={this.isEditTanggal}> &nbsp;[Mohon Diisi] &nbsp;</span>
  199. }
  200. &nbsp;bertempat di
  201. {dataSuratBA?.isEditTempat &&
  202. <span>
  203. <input type='text'
  204. defaultValue={dataSuratBA?.tempat}
  205. ref="inputTempat"
  206. onChange={() => {
  207. this.setState({ tempat: this.refs.inputTempat.value }, this.setDataSuratBA)
  208. }}
  209. />
  210. <button className='bg-transparent button-transparent border-0 fas fa-times-circle text-danger' onClick={this.isEditTempat} />
  211. <button className='bg-transparent button-transparent border-0 fas fa-check-circle text-success' onClick={() => { this.isEditTempat() }} />
  212. </span>
  213. }
  214. {dataSuratBA?.tempat || this.state?.tempat ?
  215. <span onClick={this.isEditTempat}>
  216. &nbsp;{dataSuratBA?.tempat || this.state?.tempat}
  217. </span>
  218. :
  219. <span onClick={this.isEditTempat}>[Mohon Diisi]</span>
  220. }
  221. ,
  222. telah dilakukan rapat evaluasi dan pembahasan dugaan pelanggaran penyelenggaraan oleh perguruan tinggi dan/atau badan penyelenggara {dataLaporan.data && (<span>{dataLaporan.data.pt.nama}</span>)}, yang dihadiri oleh:
  223. </p>
  224. <div className='body'>
  225. <ol>
  226. {dataLaporan.data?.peserta_penetapan_sanksi?.map((value) => <li>{value.nama}</li>)}
  227. </ol>
  228. </div>
  229. </div>
  230. <p>
  231. Berdasarkan rapat evaluasi dan pembahasan dugaan pelanggaran penyelenggaraan oleh perguruan tinggi dan/atau badan penyelenggara {dataLaporan.data && (<span>{dataLaporan.data.pt.nama}</span>)}, disampaikan sebagai berikut:
  232. </p>
  233. <div className='body'>
  234. <ol>
  235. <li>Telah dibacakan Berita Acara Evaluasi Kinerja Perguruan Tinggi {dataLaporan.data && (<span>{dataLaporan.data.pt.nama}</span>)}, tanggal
  236. {setTanggal === true || this.state?.setTanggal === true ?
  237. <span> &nbsp;{moment(tanggal || this.state?.tanggal).format("DD-MM-YYYY")}</span>
  238. :
  239. <span> &nbsp;....... &nbsp;</span>
  240. }
  241. </li>
  242. <li>Telah dilakukan pembahasan rekomendasi mengenai fakta-fakta yang ditemukan Tim EKPT Ditjen Diktiristek, dengan temuan sebagai berikut:</li>
  243. <table className='table-a'>
  244. <thead>
  245. <tr>
  246. <th rowspan="2">NO</th>
  247. <th rowspan="2">NAMA DAN IZIN PRODI</th>
  248. <th colspan="3">PELANGGARAN TERHADAP PERMENDIKBUD NO.7 TAHUN 2020</th>
  249. <th rowspan="2">SIMPULAN</th>
  250. <th rowspan="2">REKOMENDASI</th>
  251. </tr>
  252. <tr>
  253. <th>PASAL</th>
  254. <th>BUTIR PELANGGARAN</th>
  255. <th>DESKRIPSI PELANGGARAN</th>
  256. </tr>
  257. </thead>
  258. <tbody>
  259. {dataPelanggaran?.data?.map((e, i) => (
  260. <tr key={e._id}>
  261. <td>{++i}</td>
  262. {dataLaporan.data && (<td className='BA-header'>{dataLaporan.data.pt.nama}</td>)}
  263. <td>{e.pasal}</td>
  264. <td>{e.butir_pelanggaran}</td>
  265. <td>{e.pelanggaran}</td>
  266. <td>
  267. <ContentEditable
  268. html={descPelanggaran[e._id]?.simpulan || ""}
  269. disabled={false}
  270. onChange={(evt) => {
  271. this.updateValueSimpulan(evt, e._id), this.setDataSuratBA()
  272. }}
  273. />
  274. </td>
  275. <td>
  276. <ContentEditable
  277. html={descPelanggaran[e._id]?.rekomendasi || ""}
  278. disabled={false}
  279. onChange={(evt) => {
  280. this.updateValueRekomendasi(evt, e._id), this.setDataSuratBA()
  281. }}
  282. />
  283. </td>
  284. </tr>
  285. )) ||
  286. this.props.dataPelanggaran?.data?.map((e, i) => (
  287. <tr key={e._id}>
  288. <td>{++i}</td>
  289. {dataLaporan.data && (<td className='BA-header'>{dataLaporan.data.pt.nama}</td>)}
  290. <td>{e.pasal}</td>
  291. <td>{e.butir_pelanggaran}</td>
  292. <td>{e.pelanggaran}</td>
  293. <td > {this.state?.descPelanggaran[e._id]?.simpulan}</td>
  294. <td > {this.state?.descPelanggaran[e._id]?.rekomendasi}</td>
  295. </tr>
  296. ))}
  297. </tbody>
  298. </table>
  299. <li>Temuan Lain:
  300. {dataSuratBA?.isEditTemuanLain ?
  301. <span>
  302. <input style={{ height: "30px", width: "250px" }} type='textarea' defaultValue={""} ref="inputTemuan"
  303. />
  304. <button className='bg-transparent button-transparent border-0 fas fa-check-circle text-success' onClick={() => {
  305. this.updateValueTemuanLain(), this.isEditTemuanLain(), this.handleAutoSave()
  306. }} />
  307. <button className='bg-transparent button-transparent border-0 fas fa-times-circle text-danger' onClick={this.isEditTemuanLain} />
  308. </span>
  309. : <Button onClick={this.isEditTemuanLain} className=" p-0 m-0" color="success">Input Data</Button>}
  310. <ol type="a">
  311. {dataSuratBA?.temuanLain?.map((value) => <li>{value}</li>) || this.state?.temuanLain?.map((value) => <li>{value}</li>)}
  312. </ol>
  313. </li>
  314. <li>Hal-hal yang memberatkan, sebagai berikut:
  315. {dataSuratBA?.isEditKeberatan ?
  316. <span>
  317. <input style={{ height: "30px", width: "250px" }} type='text' defaultValue={""} ref="inputMemberatkan" />
  318. <button className='bg-transparent button-transparent border-0 fas fa-check-circle text-success' onClick={() => { this.updateValueMemberatkan(), this.isEditKeberatan() }} />
  319. <button className='bg-transparent button-transparent border-0 fas fa-times-circle text-danger' onClick={this.isEditKeberatan} />
  320. </span>
  321. : <Button onClick={this.isEditKeberatan} className=" p-0 m-0" color="success">Input Data</Button>}
  322. <ol type="a">
  323. {dataSuratBA?.memberatkan?.map((value) => <li>{value}</li>) || this.state?.memberatkan?.map((value) => <li>{value}</li>)}
  324. </ol>
  325. </li>
  326. <li>hal-hal yang meringankan, sebagai berikut:
  327. {dataSuratBA?.isEditMeringankan ?
  328. <span>
  329. <input type='text' defaultValue={""} ref="inputMeringankan" />
  330. <button className='bg-transparent button-transparent border-0 fas fa-check-circle text-success' onClick={() => { this.updateValueMemringankan(), this.isEditMeringankan() }} />
  331. <button className='bg-transparent button-transparent border-0 fas fa-times-circle text-danger' onClick={this.isEditMeringankan} />
  332. </span>
  333. : <Button onClick={this.isEditMeringankan} className=" p-0 m-0" color="success">Input Data</Button>}
  334. <ol type="a">
  335. {dataSuratBA?.meringankan?.map((value) => <li>{value}</li>) || this.state?.meringankan?.map((value) => <li>{value}</li>)}
  336. </ol>
  337. </li>
  338. <li>
  339. Berdasarkan pembahasan yang dilakukan, disepakati untuk merekomendasikan <strong>“Sanksi Administratif berupa
  340. {dataSuratBA?.isEditSanksi &&
  341. <span>
  342. <input type='text'
  343. defaultValue=""
  344. ref="inputsanksi"
  345. onChange={() => {
  346. this.setState({ sanksi: this.refs.inputsanksi.value }, this.setDataSuratBA)
  347. }}
  348. />
  349. <button className='bg-transparent button-transparent border-0 fas fa-times-circle text-danger' onClick={this.isEditSanksi} />
  350. <button className='bg-transparent button-transparent border-0 fas fa-check-circle text-success' onClick={() => { this.isEditSanksi() }} />
  351. </span>
  352. }
  353. {dataSuratBA?.sanksi || this.state?.sanksi ?
  354. <span onClick={this.isEditSanksi}>
  355. &nbsp;{dataSuratBA?.sanksi || this.state?.sanksi}
  356. </span>
  357. :
  358. <span onClick={this.isEditSanksi}>[Mohon Diisi]</span>
  359. }
  360. </strong>
  361. </li>
  362. </ol>
  363. </div>
  364. <p className=''>
  365. Demikian Laporan Evaluasi dan Pembahasan ini dibuat dengan sesungguhnya dan telah dibaca dan dicermati oleh peserta rapat yang hadir.
  366. </p>
  367. <p>
  368. <CopyToClipboard
  369. text={`https://dev.sidali.kemdikbud.go.id/signature/pleno-sanksi/${dataLaporan.data?._id}`}
  370. options={{ asHtml: true }}
  371. >
  372. <div>
  373. <span className="btn-radius">
  374. <Button color id="Popover1" className="btn-labeled-3" onClick={() => {
  375. this.setState({
  376. setmeState: !this.state.setmeState
  377. }, this.setDataSuratBA()), this.handleAutoSave(), this.CloseCopied()
  378. }} >
  379. <h4 className="p-0 mt-2 float-right"> <em className="fas fa-project-diagram float-left mt-1" /> &nbsp;Link Dokumen</h4>
  380. </Button>
  381. </span>
  382. <Popover placement="bottom" isOpen={this.state.copied} target="Popover1" toggle={this.Copied}>
  383. <PopoverHeader>Link Berhasil Disalin</PopoverHeader>
  384. </Popover>
  385. </div>
  386. </CopyToClipboard>
  387. </p>
  388. <table className='demo'>
  389. <tbody>
  390. <tr>
  391. <th className='thdemo' colspan="4">PESERTA RAPAT PENYUSUNAN REKOMENDASI</th>
  392. </tr>
  393. <tr className='trdemo'>
  394. <th className='trdemo'>No</th>
  395. <th className='trdemo'>Nama</th>
  396. <th className='trdemo'>Tanda Tangan</th>
  397. </tr>
  398. {dataLaporan
  399. ? dataLaporan.data?.peserta_penetapan_sanksi?.map((value, index) => (
  400. <tr>
  401. <td className='trdemo'>{index + 1}</td>
  402. <td className=' tddemo'>{value.nama}</td>
  403. <td className='tddemo'>
  404. <img
  405. style={{ width: "200px" }}
  406. src={value.ttd.path} />
  407. </td>
  408. </tr>)) : ""}
  409. </tbody>
  410. </table>
  411. {/* <div>
  412. <div id="ttd-header" className='text-center signature-border'>
  413. <span className='text-center'> PESERTA RAPAT PENYUSUNAN REKOMENDASI</span>
  414. </div>
  415. <div id="ttd">
  416. {dataLaporan
  417. ? dataLaporan.data?.peserta_penetapan_sanksi?.map((value) => (
  418. <div className='ttd-div'>
  419. <img
  420. className='sign-ttd'
  421. src={value.ttd.path} />
  422. <div className='sign-nama font-color-black'>{value.nama}</div>
  423. </div>
  424. )) : ""}
  425. </div>
  426. </div> */}
  427. </page>
  428. </div>
  429. </div >
  430. );
  431. }
  432. }
  433. export default BeritaAcara