Redudansi.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. import React, { Component } from "react";
  2. import { Row, Col, Input, FormGroup, Label, Progress, Button } from "reactstrap";
  3. import Select from "react-select";
  4. import "react-datepicker/dist/react-datepicker.css";
  5. import Swal from "sweetalert2";
  6. import * as Yup from "yup";
  7. import { connect } from "react-redux";
  8. import { Formik, Form, Field, ErrorMessage } from "formik";
  9. import { updateLaporan } from "../../actions/pelaporan"
  10. import { getCsrf } from "../../actions/security";
  11. import { ToastContainer, toast } from "react-toastify";
  12. import Router from "next/router";
  13. import { createLog } from "../../actions/log";
  14. const checkIfFilesAreTooBig = (files) => {
  15. let valid = true;
  16. if (files) {
  17. files.map((file) => {
  18. if (file.size > 15 * 1024 * 1024) {
  19. valid = false;
  20. }
  21. });
  22. }
  23. return valid;
  24. };
  25. let Dropzone = null;
  26. class DropzoneWrapper extends Component {
  27. state = {
  28. isClient: false,
  29. };
  30. componentDidMount = () => {
  31. Dropzone = require("react-dropzone").default;
  32. this.setState({ isClient: true });
  33. };
  34. render() {
  35. return Dropzone ? <Dropzone {...this.props}>{this.props.children}</Dropzone> : null;
  36. }
  37. }
  38. const ditutupSchema = Yup.object().shape({
  39. keterangan: Yup.string().required("Harus diisi"),
  40. dokumen: Yup.array().test("filesize", "Maksimal ukuran dokumen 15mb", checkIfFilesAreTooBig),
  41. });
  42. const status = [
  43. { value: "Sanksi", label: "Sanksi", className: "State-ACT" },
  44. { value: "Ditutup", label: "Ditutup", className: "State-ACT" },
  45. ];
  46. export class Redudansi extends Component {
  47. constructor(props) {
  48. super(props);
  49. const tmt_awal = new Date();
  50. this.state = {
  51. files: [],
  52. keterangan: "",
  53. selectedOption: null,
  54. };
  55. }
  56. async componentDidMount() {
  57. this.defaultStatus();
  58. }
  59. defaultStatus = async () => {
  60. return this.setState({ selectedOption: status[0] });
  61. };
  62. handleChangeSelect = (selectedOption) => this.setState({ selectedOption }, this.setDataStatusLaporan);
  63. // handleChangeSelect = (selectedOption) => {
  64. // this.state.selectedOption = selectedOption
  65. // this.setDataStatusLaporan()
  66. // }
  67. getStatus = () => (status);
  68. onDrop = (selectedFile) => {
  69. this.setState({
  70. selectedFile: selectedFile.map((file) =>
  71. Object.assign(file, {
  72. preview: URL.createObjectURL(file),
  73. })
  74. ),
  75. stat: "Added " + selectedFile.length + " file(s)",
  76. });
  77. const selectFile = this.state.selectedFile
  78. this.setState(prevState => ({
  79. files: [...prevState.files, ...selectFile]
  80. }))
  81. };
  82. logDitutup = async () => {
  83. const getToken = await getCsrf();
  84. const _csrf = getToken.token;
  85. const { token } = this.props;
  86. await createLog(token, { aktivitas: `Berhasil menutup laporan, id: ${this.props.id}`, _csrf: _csrf, menu: "Sanksi" });
  87. }
  88. handleTutupLaporan = async (data, value) => {
  89. if (this.props.role === 2024) {
  90. Swal.fire({
  91. icon: 'error',
  92. title: 'Oops...',
  93. html: 'Maaf anda tidak memiliki akses untuk menyelesaikan<p> proses ini.</p>',
  94. confirmButtonColor: "#3e3a8e",
  95. confirmButtonText: 'Oke'
  96. })
  97. } else {
  98. const getToken = await getCsrf();
  99. const _csrf = getToken.token;
  100. const { token } = this.props;
  101. const formdata = new FormData();
  102. formdata.append("keterangan", data.keterangan);
  103. this.state.files.forEach((e) => {
  104. formdata.append("dokumen", e);
  105. });
  106. formdata.append("aktif", "false");
  107. await toast.promise(updateLaporan(token, this.props.id, formdata, _csrf + `&redudansi=true`), {
  108. pending: "Loading",
  109. success: {
  110. render: "success",
  111. autoClose: 1000
  112. },
  113. error: "Error",
  114. });
  115. await this.logDitutup()
  116. await Router.push({
  117. pathname: "/app/sanksi",
  118. });
  119. }
  120. };
  121. setDataStatusLaporan = () => {
  122. this.props.setDataStatusLaporan(this.state)
  123. }
  124. render() {
  125. const { files, selectedOption } = this.state;
  126. const removeFile = file => () => {
  127. const newFiles = [...files]
  128. newFiles.splice(newFiles.indexOf(file), 1)
  129. this.setState({
  130. files: newFiles,
  131. });
  132. }
  133. const thumbs = files.map((file, index) => (
  134. <p>
  135. <em className="far fa-file" />&nbsp;&nbsp;{file.name}
  136. <button className="bg-transparent button-transparent border-0 fas fa-trash text-danger float-right" onClick={removeFile(file)} />
  137. </p>
  138. ));
  139. return (
  140. <>
  141. <Formik
  142. enableReinitialize={true}
  143. initialValues={{
  144. status: this.getStatus()[0],
  145. keterangan: "",
  146. dokumen: [],
  147. }}
  148. validationSchema={selectedOption?.value === this.getStatus()[1].value ? ditutupSchema : null}
  149. onSubmit={this.handleTutupLaporan}
  150. >
  151. {({ isSubmitting }) => (
  152. <Form>
  153. <FormGroup row>
  154. <label className="col-md-2 col-form-label font-weight-bold font-color-black">Status Laporan</label>
  155. <div className="col-md-10">
  156. <Field name="status">
  157. {({ field, form }) => (
  158. <Select
  159. value={field.value}
  160. onChange={(e) => {
  161. form.setFieldValue(field.name, e);
  162. this.handleChangeSelect(e);
  163. }}
  164. options={this.getStatus()}
  165. required
  166. />
  167. )}
  168. </Field>
  169. <ErrorMessage name="status" component="div" className="form-text text-danger" />
  170. </div>
  171. </FormGroup>
  172. {selectedOption?.value === this.getStatus()[0].value ? (
  173. ""
  174. ) : (
  175. <div>
  176. <FormGroup row>
  177. <label className="col-md-2 col-form-label">Keterangan<span className=" text-danger">*</span></label>
  178. <div className="col-md-10">
  179. <Field name="keterangan">{({ field, form }) => <Input type="text" placeholder="Keterangan" {...field} />}</Field>
  180. <ErrorMessage name="keterangan" component="div" className="form-text text-danger" />
  181. </div>
  182. </FormGroup>
  183. <FormGroup row>
  184. <label className="col-md-2 col-form-label">Upload File Pendukung<span className="text-danger">*</span></label>
  185. <div className="col-md-10">
  186. <Field name="dokumen">
  187. {({ field, form, meta }) => (
  188. <DropzoneWrapper
  189. className=""
  190. onDrop={(e) => {
  191. this.onDrop(e);
  192. form.setFieldValue(field.name, e);
  193. }}
  194. >
  195. {({ getRootProps, getInputProps, isDragActive }) => {
  196. return (
  197. <div {...getRootProps()} className={"dropzone card" + (isDragActive ? "dropzone-drag-active" : "")}>
  198. <input name="dokumen" {...getInputProps()} />
  199. <div className="dropzone-style-1">
  200. <div className="center-ver-hor dropzone-previews flex">{this.state.files.length > 0 ?
  201. <div className="text-center fa-2x icon-cloud-upload mr-2 ">
  202. <h5 className="text-center dz-default dz-message">Klik untuk tambah file</h5>
  203. </div> :
  204. <div className="text-center fa-2x icon-cloud-upload mr-2 ">
  205. <h5 className="text-center dz-default dz-message">Klik untuk upload dokumen</h5>
  206. </div>
  207. }
  208. </div>
  209. </div>
  210. <div className="d-flex align-items-center">
  211. <small className="ml-auto">
  212. <button
  213. type="button"
  214. className="btn btn-link"
  215. onClick={(e) => {
  216. this.clearFiles(e);
  217. form.setFieldValue(field.name, []);
  218. }}
  219. >
  220. Reset dokumen
  221. </button>
  222. </small>
  223. </div>
  224. </div>
  225. );
  226. }}
  227. </DropzoneWrapper>
  228. )}
  229. </Field>
  230. {thumbs}
  231. <ErrorMessage name="dokumen" component="div" className="form-text text-danger" />
  232. <p className="mrgn-top-5 font-color-black">
  233. Ukuran setiap dokumen maksimal 15mb
  234. </p>
  235. </div>
  236. <FormGroup>
  237. <div className="col-xl-10">
  238. <Button color className="btn-login width-133 mt-4" type="submit" disabled={isSubmitting}>
  239. <span className="font-color-white">
  240. Tutup Laporan
  241. </span>
  242. </Button>
  243. </div>
  244. </FormGroup>
  245. </FormGroup>
  246. </div>
  247. )}
  248. </Form>
  249. )}
  250. </Formik>
  251. </>
  252. );
  253. }
  254. }
  255. // const mapStateToProps = (state) => ({ user: state.user, token: state.token });
  256. // export default connect(mapStateToProps)(Redudansi);
  257. export default Redudansi