|  | @@ -1,277 +1,277 @@
 | 
	
		
			
				|  |  | -import React, { Component } from "react";
 | 
	
		
			
				|  |  | -import Router from "next/router";
 | 
	
		
			
				|  |  | -import { getPelanggaranPublic } from "@/actions/pelanggaran";
 | 
	
		
			
				|  |  | -import { createPelaporan } from "@/actions/pelaporan";
 | 
	
		
			
				|  |  | -import Select from "react-select";
 | 
	
		
			
				|  |  | -import { Row, Col, FormGroup, Input } from "reactstrap";
 | 
	
		
			
				|  |  | -import { connect } from "react-redux";
 | 
	
		
			
				|  |  | -import { ToastContainer, toast } from "react-toastify";
 | 
	
		
			
				|  |  | -import moment from "moment";
 | 
	
		
			
				|  |  | -import "react-toastify/dist/ReactToastify.css";
 | 
	
		
			
				|  |  | -import { Formik, Form, Field, ErrorMessage } from "formik";
 | 
	
		
			
				|  |  | -import * as Yup from "yup";
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -let Dropzone = null;
 | 
	
		
			
				|  |  | -class DropzoneWrapper extends Component {
 | 
	
		
			
				|  |  | -	state = {
 | 
	
		
			
				|  |  | -		isClient: false,
 | 
	
		
			
				|  |  | -	};
 | 
	
		
			
				|  |  | -	componentDidMount = () => {
 | 
	
		
			
				|  |  | -		Dropzone = require("react-dropzone").default;
 | 
	
		
			
				|  |  | -		this.setState({ isClient: true });
 | 
	
		
			
				|  |  | -	};
 | 
	
		
			
				|  |  | -	render() {
 | 
	
		
			
				|  |  | -		return Dropzone ? <Dropzone {...this.props}>{this.props.children}</Dropzone> : null;
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -const checkIfFilesAreTooBig = (files) => {
 | 
	
		
			
				|  |  | -	let valid = true;
 | 
	
		
			
				|  |  | -	if (files) {
 | 
	
		
			
				|  |  | -		files.map((file) => {
 | 
	
		
			
				|  |  | -			if (file.size > 15 * 1024 * 1024) {
 | 
	
		
			
				|  |  | -				valid = false;
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -		});
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	return valid;
 | 
	
		
			
				|  |  | -};
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -const checkIfFilesAreCorrectType = (files) => {
 | 
	
		
			
				|  |  | -	let valid = true;
 | 
	
		
			
				|  |  | -	if (files) {
 | 
	
		
			
				|  |  | -		files.map((file) => {
 | 
	
		
			
				|  |  | -			if (!["image/jpeg", "image/png"].includes(file.type)) {
 | 
	
		
			
				|  |  | -				valid = false;
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -		});
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	return valid;
 | 
	
		
			
				|  |  | -};
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -const selectInstanceId = 1;
 | 
	
		
			
				|  |  | -const laporanSchema = Yup.object().shape({
 | 
	
		
			
				|  |  | -	no_laporan: Yup.string().required("Harap Diisi"),
 | 
	
		
			
				|  |  | -	keterangan: Yup.string().min(3).max(200).required("Harap Diisi"),
 | 
	
		
			
				|  |  | -	pelanggaran: Yup.array().min(1).required("Harap Diisi"),
 | 
	
		
			
				|  |  | -	dokumen: Yup.array().notRequired().test("filesize", "Maksimal ukuran dokumen 15mb", checkIfFilesAreTooBig),
 | 
	
		
			
				|  |  | -});
 | 
	
		
			
				|  |  | -export class InputData extends Component {
 | 
	
		
			
				|  |  | -	constructor(props) {
 | 
	
		
			
				|  |  | -		super(props);
 | 
	
		
			
				|  |  | -		this.state = {
 | 
	
		
			
				|  |  | -			dropdownOpen: false,
 | 
	
		
			
				|  |  | -			splitButtonOpen: false,
 | 
	
		
			
				|  |  | -			selectedOptionMulti: [],
 | 
	
		
			
				|  |  | -			stat: "Waiting to add files..",
 | 
	
		
			
				|  |  | -			pelaporanNumber: moment(new Date()).format("DDMM") + "" + Math.floor(Math.random() * 1000000),
 | 
	
		
			
				|  |  | -			keteranganLaporan: "",
 | 
	
		
			
				|  |  | -			files: [],
 | 
	
		
			
				|  |  | -			pelanggaran: [],
 | 
	
		
			
				|  |  | -		};
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	componentDidMount = async () => {
 | 
	
		
			
				|  |  | -		const pelanggaran = await getPelanggaranPublic();
 | 
	
		
			
				|  |  | -		this.setState({ pelanggaran });
 | 
	
		
			
				|  |  | -	};
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	optionsJenisPelanggaran = (pelanggaran) => {
 | 
	
		
			
				|  |  | -		return pelanggaran.data.map((e) => ({ value: e._id, label: e.pelanggaran, className: "State-ACT" }));
 | 
	
		
			
				|  |  | -	};
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	setKeteranganPelaporan = (e) => {
 | 
	
		
			
				|  |  | -		this.setState({ keteranganLaporan: e.target.value });
 | 
	
		
			
				|  |  | -	};
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	toggleDropDown = () => {
 | 
	
		
			
				|  |  | -		this.setState({
 | 
	
		
			
				|  |  | -			dropdownOpen: !this.state.dropdownOpen,
 | 
	
		
			
				|  |  | -		});
 | 
	
		
			
				|  |  | -	};
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	toggleSplit = () => {
 | 
	
		
			
				|  |  | -		this.setState({
 | 
	
		
			
				|  |  | -			splitButtonOpen: !this.state.splitButtonOpen,
 | 
	
		
			
				|  |  | -		});
 | 
	
		
			
				|  |  | -	};
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	handleChangeSelectMulti = (selectedOptionMulti) => {
 | 
	
		
			
				|  |  | -		this.setState({ selectedOptionMulti });
 | 
	
		
			
				|  |  | -	};
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	onDrop = (files) => {
 | 
	
		
			
				|  |  | -		this.setState({
 | 
	
		
			
				|  |  | -			files: files.map((file) =>
 | 
	
		
			
				|  |  | -				Object.assign(file, {
 | 
	
		
			
				|  |  | -					preview: URL.createObjectURL(file),
 | 
	
		
			
				|  |  | -				})
 | 
	
		
			
				|  |  | -			),
 | 
	
		
			
				|  |  | -			stat: "Added " + files.length + " file(s)",
 | 
	
		
			
				|  |  | -		});
 | 
	
		
			
				|  |  | -	};
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	uploadFiles = (e) => {
 | 
	
		
			
				|  |  | -		e.preventDefault();
 | 
	
		
			
				|  |  | -		e.stopPropagation();
 | 
	
		
			
				|  |  | -		this.setState({
 | 
	
		
			
				|  |  | -			stat: this.state.files.length ? "Dropzone ready to upload " + this.state.files.length + " file(s)" : "No files added.",
 | 
	
		
			
				|  |  | -		});
 | 
	
		
			
				|  |  | -	};
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	clearFiles = (e) => {
 | 
	
		
			
				|  |  | -		e.preventDefault();
 | 
	
		
			
				|  |  | -		e.stopPropagation();
 | 
	
		
			
				|  |  | -		this.setState({
 | 
	
		
			
				|  |  | -			stat: this.state.files.length ? this.state.files.length + " file(s) cleared." : "No files to clear.",
 | 
	
		
			
				|  |  | -		});
 | 
	
		
			
				|  |  | -		this.setState({
 | 
	
		
			
				|  |  | -			files: [],
 | 
	
		
			
				|  |  | -		});
 | 
	
		
			
				|  |  | -	};
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	onSubmit = async (data) => {
 | 
	
		
			
				|  |  | -		const { token, query } = this.props;
 | 
	
		
			
				|  |  | -		const formdata = new FormData();
 | 
	
		
			
				|  |  | -		formdata.append("no_laporan", data.no_laporan);
 | 
	
		
			
				|  |  | -		formdata.append("pt_id", query.ptId);
 | 
	
		
			
				|  |  | -		formdata.append("keterangan", data.keterangan);
 | 
	
		
			
				|  |  | -		formdata.append("pelanggaran_id", data.pelanggaran.join());
 | 
	
		
			
				|  |  | -		if (data.dokumen.length > 0) {
 | 
	
		
			
				|  |  | -			data.dokumen.forEach((e) => {
 | 
	
		
			
				|  |  | -				formdata.append("dokumen", e);
 | 
	
		
			
				|  |  | -			});
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		const create = createPelaporan(token, formdata);
 | 
	
		
			
				|  |  | -		await toast.promise(create, {
 | 
	
		
			
				|  |  | -			pending: "Loading...",
 | 
	
		
			
				|  |  | -			success: "Berhasil buat laporan",
 | 
	
		
			
				|  |  | -			error: "Gagal buat laporan",
 | 
	
		
			
				|  |  | -		});
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		Router.push({
 | 
	
		
			
				|  |  | -			pathname: "/app/pelaporan",
 | 
	
		
			
				|  |  | -		});
 | 
	
		
			
				|  |  | -	};
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	render() {
 | 
	
		
			
				|  |  | -		const { selectedOptionMulti, files, pelanggaran } = this.state;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		const thumbs = files.map((file, index) => (
 | 
	
		
			
				|  |  | -			<Col md={3} key={index}>
 | 
	
		
			
				|  |  | -				<img className="img-fluid mb-2" src={file.preview} alt="Item" />
 | 
	
		
			
				|  |  | -			</Col>
 | 
	
		
			
				|  |  | -		));
 | 
	
		
			
				|  |  | -		return (
 | 
	
		
			
				|  |  | -			<Formik
 | 
	
		
			
				|  |  | -				initialValues={{
 | 
	
		
			
				|  |  | -					no_laporan: this.state.pelaporanNumber,
 | 
	
		
			
				|  |  | -					keterangan: "",
 | 
	
		
			
				|  |  | -					pelanggaran: [],
 | 
	
		
			
				|  |  | -					dokumen: [],
 | 
	
		
			
				|  |  | -				}}
 | 
	
		
			
				|  |  | -				validationSchema={laporanSchema}
 | 
	
		
			
				|  |  | -				onSubmit={this.onSubmit}
 | 
	
		
			
				|  |  | -			>
 | 
	
		
			
				|  |  | -				{({ isSubmitting }) => (
 | 
	
		
			
				|  |  | -					<Form>
 | 
	
		
			
				|  |  | -						<FormGroup row>
 | 
	
		
			
				|  |  | -							<label className="col-md-2 col-form-label">Nomor Pelaporan</label>
 | 
	
		
			
				|  |  | -							<div className="col-md-10">
 | 
	
		
			
				|  |  | -								<Input type="text" name="no_laporan" disabled value={this.state.pelaporanNumber} />
 | 
	
		
			
				|  |  | -								<span className="form-text">Nomor pelaporan akan digenerate otomatis dari sistem</span>
 | 
	
		
			
				|  |  | -							</div>
 | 
	
		
			
				|  |  | -						</FormGroup>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -						<FormGroup row>
 | 
	
		
			
				|  |  | -							<label className="col-md-2 col-form-label">Jenis Pelanggaran</label>
 | 
	
		
			
				|  |  | -							<div className="col-md-10">
 | 
	
		
			
				|  |  | -								<Field name="pelanggaran">
 | 
	
		
			
				|  |  | -									{({ field, form, meta }) => (
 | 
	
		
			
				|  |  | -										<Select
 | 
	
		
			
				|  |  | -											instanceId={selectInstanceId + 1}
 | 
	
		
			
				|  |  | -											name="pelanggaran"
 | 
	
		
			
				|  |  | -											isMulti
 | 
	
		
			
				|  |  | -											value={selectedOptionMulti}
 | 
	
		
			
				|  |  | -											onChange={(e) => {
 | 
	
		
			
				|  |  | -												this.handleChangeSelectMulti(e);
 | 
	
		
			
				|  |  | -												form.setFieldValue(
 | 
	
		
			
				|  |  | -													field.name,
 | 
	
		
			
				|  |  | -													e.map((e) => e.value)
 | 
	
		
			
				|  |  | -												);
 | 
	
		
			
				|  |  | -											}}
 | 
	
		
			
				|  |  | -											options={pelanggaran.data ? this.optionsJenisPelanggaran(pelanggaran) : []}
 | 
	
		
			
				|  |  | -											required
 | 
	
		
			
				|  |  | -										/>
 | 
	
		
			
				|  |  | -									)}
 | 
	
		
			
				|  |  | -								</Field>
 | 
	
		
			
				|  |  | -								<ErrorMessage name="pelanggaran" component="div" className="form-text text-danger" />
 | 
	
		
			
				|  |  | -							</div>
 | 
	
		
			
				|  |  | -						</FormGroup>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -						<FormGroup row>
 | 
	
		
			
				|  |  | -							<label className="col-md-2 col-form-label">Keterangan Laporan</label>
 | 
	
		
			
				|  |  | -							<div className="col-md-10">
 | 
	
		
			
				|  |  | -								<Field name="keterangan">{({ field }) => <Input type="textarea" placeholder="Keterangan Laporan" {...field} />}</Field>
 | 
	
		
			
				|  |  | -								<ErrorMessage name="keterangan" component="div" className="form-text text-danger" />
 | 
	
		
			
				|  |  | -							</div>
 | 
	
		
			
				|  |  | -						</FormGroup>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -						<FormGroup row>
 | 
	
		
			
				|  |  | -							<label className="col-md-2 col-form-label">Upload File Pendukung</label>
 | 
	
		
			
				|  |  | -							<div className="col-md-10">
 | 
	
		
			
				|  |  | -								<Field name="dokumen">
 | 
	
		
			
				|  |  | -									{({ field, form, meta }) => (
 | 
	
		
			
				|  |  | -										<DropzoneWrapper
 | 
	
		
			
				|  |  | -											className=""
 | 
	
		
			
				|  |  | -											onDrop={(e) => {
 | 
	
		
			
				|  |  | -												this.onDrop(e);
 | 
	
		
			
				|  |  | -												form.setFieldValue(field.name, e);
 | 
	
		
			
				|  |  | -											}}
 | 
	
		
			
				|  |  | -										>
 | 
	
		
			
				|  |  | -											{({ getRootProps, getInputProps, isDragActive }) => {
 | 
	
		
			
				|  |  | -												return (
 | 
	
		
			
				|  |  | -													<div {...getRootProps()} className={"dropzone card p-3 " + (isDragActive ? "dropzone-drag-active" : "")}>
 | 
	
		
			
				|  |  | -														<input name="dokumen" {...getInputProps()} />
 | 
	
		
			
				|  |  | -														<div className="dropzone-previews flex">{this.state.files.length > 0 ? <Row>{thumbs}</Row> : <div className="text-center dz-default dz-message">Drop files here to upload</div>}</div>
 | 
	
		
			
				|  |  | -														<div className="d-flex align-items-center">
 | 
	
		
			
				|  |  | -															<small className="ml-auto">
 | 
	
		
			
				|  |  | -																<button
 | 
	
		
			
				|  |  | -																	type="button"
 | 
	
		
			
				|  |  | -																	className="btn btn-link"
 | 
	
		
			
				|  |  | -																	onClick={(e) => {
 | 
	
		
			
				|  |  | -																		this.clearFiles(e);
 | 
	
		
			
				|  |  | -																		form.setFieldValue(field.name, []);
 | 
	
		
			
				|  |  | -																	}}
 | 
	
		
			
				|  |  | -																>
 | 
	
		
			
				|  |  | -																	Clear files
 | 
	
		
			
				|  |  | -																</button>
 | 
	
		
			
				|  |  | -															</small>
 | 
	
		
			
				|  |  | -														</div>
 | 
	
		
			
				|  |  | -													</div>
 | 
	
		
			
				|  |  | -												);
 | 
	
		
			
				|  |  | -											}}
 | 
	
		
			
				|  |  | -										</DropzoneWrapper>
 | 
	
		
			
				|  |  | -									)}
 | 
	
		
			
				|  |  | -								</Field>
 | 
	
		
			
				|  |  | -								<ErrorMessage name="dokumen" component="div" className="form-text text-danger" />
 | 
	
		
			
				|  |  | -							</div>
 | 
	
		
			
				|  |  | -						</FormGroup>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -						<FormGroup row>
 | 
	
		
			
				|  |  | -							<div className="col-xl-10">
 | 
	
		
			
				|  |  | -								<button className="btn btn-sm btn-primary" type="submit" disabled={isSubmitting}>
 | 
	
		
			
				|  |  | -									Submit Laporan
 | 
	
		
			
				|  |  | -								</button>
 | 
	
		
			
				|  |  | -							</div>
 | 
	
		
			
				|  |  | -						</FormGroup>
 | 
	
		
			
				|  |  | -					</Form>
 | 
	
		
			
				|  |  | -				)}
 | 
	
		
			
				|  |  | -			</Formik>
 | 
	
		
			
				|  |  | -		);
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -const mapStateToProps = (state) => ({ user: state.user, token: state.token });
 | 
	
		
			
				|  |  | -export default connect(mapStateToProps)(InputData);
 | 
	
		
			
				|  |  | +import React, { Component } from "react";
 | 
	
		
			
				|  |  | +import Router from "next/router";
 | 
	
		
			
				|  |  | +import { getPelanggaranPublic } from "@/actions/pelanggaran";
 | 
	
		
			
				|  |  | +import { createPelaporan } from "@/actions/pelaporan";
 | 
	
		
			
				|  |  | +import Select from "react-select";
 | 
	
		
			
				|  |  | +import { Row, Col, FormGroup, Input } from "reactstrap";
 | 
	
		
			
				|  |  | +import { connect } from "react-redux";
 | 
	
		
			
				|  |  | +import { ToastContainer, toast } from "react-toastify";
 | 
	
		
			
				|  |  | +import moment from "moment";
 | 
	
		
			
				|  |  | +import "react-toastify/dist/ReactToastify.css";
 | 
	
		
			
				|  |  | +import { Formik, Form, Field, ErrorMessage } from "formik";
 | 
	
		
			
				|  |  | +import * as Yup from "yup";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +let Dropzone = null;
 | 
	
		
			
				|  |  | +class DropzoneWrapper extends Component {
 | 
	
		
			
				|  |  | +	state = {
 | 
	
		
			
				|  |  | +		isClient: false,
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  | +	componentDidMount = () => {
 | 
	
		
			
				|  |  | +		Dropzone = require("react-dropzone").default;
 | 
	
		
			
				|  |  | +		this.setState({ isClient: true });
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  | +	render() {
 | 
	
		
			
				|  |  | +		return Dropzone ? <Dropzone {...this.props}>{this.props.children}</Dropzone> : null;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const checkIfFilesAreTooBig = (files) => {
 | 
	
		
			
				|  |  | +	let valid = true;
 | 
	
		
			
				|  |  | +	if (files) {
 | 
	
		
			
				|  |  | +		files.map((file) => {
 | 
	
		
			
				|  |  | +			if (file.size > 15 * 1024 * 1024) {
 | 
	
		
			
				|  |  | +				valid = false;
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		});
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	return valid;
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const checkIfFilesAreCorrectType = (files) => {
 | 
	
		
			
				|  |  | +	let valid = true;
 | 
	
		
			
				|  |  | +	if (files) {
 | 
	
		
			
				|  |  | +		files.map((file) => {
 | 
	
		
			
				|  |  | +			if (!["image/jpeg", "image/png"].includes(file.type)) {
 | 
	
		
			
				|  |  | +				valid = false;
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		});
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	return valid;
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const selectInstanceId = 1;
 | 
	
		
			
				|  |  | +const laporanSchema = Yup.object().shape({
 | 
	
		
			
				|  |  | +	no_laporan: Yup.string().required("Harap Diisi"),
 | 
	
		
			
				|  |  | +	keterangan: Yup.string().min(3).max(200).required("Wajib Diisi"),
 | 
	
		
			
				|  |  | +	pelanggaran: Yup.array().min(1, "Wajib Diisi").required("Wajib Diisi"),
 | 
	
		
			
				|  |  | +	dokumen: Yup.array().min(1, "Wajib Upload Dokumen").required().test("filesize", "Maksimal ukuran dokumen 15mb", checkIfFilesAreTooBig,),
 | 
	
		
			
				|  |  | +});
 | 
	
		
			
				|  |  | +export class InputData extends Component {
 | 
	
		
			
				|  |  | +	constructor(props) {
 | 
	
		
			
				|  |  | +		super(props);
 | 
	
		
			
				|  |  | +		this.state = {
 | 
	
		
			
				|  |  | +			dropdownOpen: false,
 | 
	
		
			
				|  |  | +			splitButtonOpen: false,
 | 
	
		
			
				|  |  | +			selectedOptionMulti: [],
 | 
	
		
			
				|  |  | +			stat: "Waiting to add files..",
 | 
	
		
			
				|  |  | +			pelaporanNumber: moment(new Date()).format("DDMM") + "" + Math.floor(Math.random() * 1000000),
 | 
	
		
			
				|  |  | +			keteranganLaporan: "",
 | 
	
		
			
				|  |  | +			files: [],
 | 
	
		
			
				|  |  | +			pelanggaran: [],
 | 
	
		
			
				|  |  | +		};
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	componentDidMount = async () => {
 | 
	
		
			
				|  |  | +		const pelanggaran = await getPelanggaranPublic();
 | 
	
		
			
				|  |  | +		this.setState({ pelanggaran });
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	optionsJenisPelanggaran = (pelanggaran) => {
 | 
	
		
			
				|  |  | +		return pelanggaran.data.map((e) => ({ value: e._id, label: e.pelanggaran, className: "State-ACT" }));
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	setKeteranganPelaporan = (e) => {
 | 
	
		
			
				|  |  | +		this.setState({ keteranganLaporan: e.target.value });
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	toggleDropDown = () => {
 | 
	
		
			
				|  |  | +		this.setState({
 | 
	
		
			
				|  |  | +			dropdownOpen: !this.state.dropdownOpen,
 | 
	
		
			
				|  |  | +		});
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	toggleSplit = () => {
 | 
	
		
			
				|  |  | +		this.setState({
 | 
	
		
			
				|  |  | +			splitButtonOpen: !this.state.splitButtonOpen,
 | 
	
		
			
				|  |  | +		});
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	handleChangeSelectMulti = (selectedOptionMulti) => {
 | 
	
		
			
				|  |  | +		this.setState({ selectedOptionMulti });
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	onDrop = (files) => {
 | 
	
		
			
				|  |  | +		this.setState({
 | 
	
		
			
				|  |  | +			files: files.map((file) =>
 | 
	
		
			
				|  |  | +				Object.assign(file, {
 | 
	
		
			
				|  |  | +					preview: URL.createObjectURL(file),
 | 
	
		
			
				|  |  | +				})
 | 
	
		
			
				|  |  | +			),
 | 
	
		
			
				|  |  | +			stat: "Added " + files.length + " file(s)",
 | 
	
		
			
				|  |  | +		});
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	uploadFiles = (e) => {
 | 
	
		
			
				|  |  | +		e.preventDefault();
 | 
	
		
			
				|  |  | +		e.stopPropagation();
 | 
	
		
			
				|  |  | +		this.setState({
 | 
	
		
			
				|  |  | +			stat: this.state.files.length ? "Dropzone ready to upload " + this.state.files.length + " file(s)" : "No files added.",
 | 
	
		
			
				|  |  | +		});
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	clearFiles = (e) => {
 | 
	
		
			
				|  |  | +		e.preventDefault();
 | 
	
		
			
				|  |  | +		e.stopPropagation();
 | 
	
		
			
				|  |  | +		this.setState({
 | 
	
		
			
				|  |  | +			stat: this.state.files.length ? this.state.files.length + " file(s) cleared." : "No files to clear.",
 | 
	
		
			
				|  |  | +		});
 | 
	
		
			
				|  |  | +		this.setState({
 | 
	
		
			
				|  |  | +			files: [],
 | 
	
		
			
				|  |  | +		});
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	onSubmit = async (data) => {
 | 
	
		
			
				|  |  | +		const { token, query } = this.props;
 | 
	
		
			
				|  |  | +		const formdata = new FormData();
 | 
	
		
			
				|  |  | +		formdata.append("no_laporan", data.no_laporan);
 | 
	
		
			
				|  |  | +		formdata.append("pt_id", query.ptId);
 | 
	
		
			
				|  |  | +		formdata.append("keterangan", data.keterangan);
 | 
	
		
			
				|  |  | +		formdata.append("pelanggaran", data.pelanggaran.join());
 | 
	
		
			
				|  |  | +		if (data.dokumen.length > 0) {
 | 
	
		
			
				|  |  | +			data.dokumen.forEach((e) => {
 | 
	
		
			
				|  |  | +				formdata.append("dokumen", e);
 | 
	
		
			
				|  |  | +			});
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		const create = createPelaporan(token, formdata);
 | 
	
		
			
				|  |  | +		await toast.promise(create, {
 | 
	
		
			
				|  |  | +			pending: "Loading...",
 | 
	
		
			
				|  |  | +			success: "Berhasil buat laporan",
 | 
	
		
			
				|  |  | +			error: "Gagal buat laporan",
 | 
	
		
			
				|  |  | +		});
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		Router.push({
 | 
	
		
			
				|  |  | +			pathname: "/app/pelaporan",
 | 
	
		
			
				|  |  | +		});
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	render() {
 | 
	
		
			
				|  |  | +		const { selectedOptionMulti, files, pelanggaran } = this.state;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		const thumbs = files.map((file, index) => (
 | 
	
		
			
				|  |  | +			<Col md={3} key={index}>
 | 
	
		
			
				|  |  | +				<img className="img-fluid mb-2" src={file.preview} alt="Item" />
 | 
	
		
			
				|  |  | +			</Col>
 | 
	
		
			
				|  |  | +		));
 | 
	
		
			
				|  |  | +		return (
 | 
	
		
			
				|  |  | +			<Formik
 | 
	
		
			
				|  |  | +				initialValues={{
 | 
	
		
			
				|  |  | +					no_laporan: this.state.pelaporanNumber,
 | 
	
		
			
				|  |  | +					keterangan: "",
 | 
	
		
			
				|  |  | +					pelanggaran: [],
 | 
	
		
			
				|  |  | +					dokumen: [],
 | 
	
		
			
				|  |  | +				}}
 | 
	
		
			
				|  |  | +				validationSchema={laporanSchema}
 | 
	
		
			
				|  |  | +				onSubmit={this.onSubmit}
 | 
	
		
			
				|  |  | +			>
 | 
	
		
			
				|  |  | +				{({ isSubmitting }) => (
 | 
	
		
			
				|  |  | +					<Form>
 | 
	
		
			
				|  |  | +						<FormGroup row>
 | 
	
		
			
				|  |  | +							<label className="col-md-2 col-form-label">Nomor Pelaporan</label>
 | 
	
		
			
				|  |  | +							<div className="col-md-10">
 | 
	
		
			
				|  |  | +								<Input type="text" name="no_laporan" disabled value={this.state.pelaporanNumber} />
 | 
	
		
			
				|  |  | +								<span className="form-text">Nomor pelaporan akan digenerate otomatis dari sistem</span>
 | 
	
		
			
				|  |  | +							</div>
 | 
	
		
			
				|  |  | +						</FormGroup>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +						<FormGroup row>
 | 
	
		
			
				|  |  | +							<label className="col-md-2 col-form-label">Jenis Pelanggaran</label>
 | 
	
		
			
				|  |  | +							<div className="col-md-10">
 | 
	
		
			
				|  |  | +								<Field name="pelanggaran">
 | 
	
		
			
				|  |  | +									{({ field, form, meta }) => (
 | 
	
		
			
				|  |  | +										<Select
 | 
	
		
			
				|  |  | +											instanceId={selectInstanceId + 1}
 | 
	
		
			
				|  |  | +											name="pelanggaran"
 | 
	
		
			
				|  |  | +											isMulti
 | 
	
		
			
				|  |  | +											value={selectedOptionMulti}
 | 
	
		
			
				|  |  | +											onChange={(e) => {
 | 
	
		
			
				|  |  | +												this.handleChangeSelectMulti(e);
 | 
	
		
			
				|  |  | +												form.setFieldValue(
 | 
	
		
			
				|  |  | +													field.name,
 | 
	
		
			
				|  |  | +													e.map((e) => e.value)
 | 
	
		
			
				|  |  | +												);
 | 
	
		
			
				|  |  | +											}}
 | 
	
		
			
				|  |  | +											options={pelanggaran.data ? this.optionsJenisPelanggaran(pelanggaran) : []}
 | 
	
		
			
				|  |  | +											required
 | 
	
		
			
				|  |  | +										/>
 | 
	
		
			
				|  |  | +									)}
 | 
	
		
			
				|  |  | +								</Field>
 | 
	
		
			
				|  |  | +								<ErrorMessage name="pelanggaran" component="div" className="form-text text-danger" />
 | 
	
		
			
				|  |  | +							</div>
 | 
	
		
			
				|  |  | +						</FormGroup>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +						<FormGroup row>
 | 
	
		
			
				|  |  | +							<label className="col-md-2 col-form-label">Keterangan Laporan</label>
 | 
	
		
			
				|  |  | +							<div className="col-md-10">
 | 
	
		
			
				|  |  | +								<Field name="keterangan">{({ field }) => <Input type="textarea" placeholder="Keterangan Laporan" {...field} />}</Field>
 | 
	
		
			
				|  |  | +								<ErrorMessage name="keterangan" component="div" className="form-text text-danger" />
 | 
	
		
			
				|  |  | +							</div>
 | 
	
		
			
				|  |  | +						</FormGroup>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +						<FormGroup row>
 | 
	
		
			
				|  |  | +							<label className="col-md-2 col-form-label">Upload File Pendukung</label>
 | 
	
		
			
				|  |  | +							<div className="col-md-10">
 | 
	
		
			
				|  |  | +								<Field name="dokumen">
 | 
	
		
			
				|  |  | +									{({ field, form, meta }) => (
 | 
	
		
			
				|  |  | +										<DropzoneWrapper
 | 
	
		
			
				|  |  | +											className=""
 | 
	
		
			
				|  |  | +											onDrop={(e) => {
 | 
	
		
			
				|  |  | +												this.onDrop(e);
 | 
	
		
			
				|  |  | +												form.setFieldValue(field.name, e);
 | 
	
		
			
				|  |  | +											}}
 | 
	
		
			
				|  |  | +										>
 | 
	
		
			
				|  |  | +											{({ getRootProps, getInputProps, isDragActive }) => {
 | 
	
		
			
				|  |  | +												return (
 | 
	
		
			
				|  |  | +													<div {...getRootProps()} className={"dropzone card p-3 " + (isDragActive ? "dropzone-drag-active" : "")}>
 | 
	
		
			
				|  |  | +														<input name="dokumen" {...getInputProps()} />
 | 
	
		
			
				|  |  | +														<div className="dropzone-previews flex">{this.state.files.length > 0 ? <Row>{thumbs}</Row> : <div className="text-center dz-default dz-message">Drop files here to upload</div>}</div>
 | 
	
		
			
				|  |  | +														<div className="d-flex align-items-center">
 | 
	
		
			
				|  |  | +															<small className="ml-auto">
 | 
	
		
			
				|  |  | +																<button
 | 
	
		
			
				|  |  | +																	type="button"
 | 
	
		
			
				|  |  | +																	className="btn btn-link"
 | 
	
		
			
				|  |  | +																	onClick={(e) => {
 | 
	
		
			
				|  |  | +																		this.clearFiles(e);
 | 
	
		
			
				|  |  | +																		form.setFieldValue(field.name, []);
 | 
	
		
			
				|  |  | +																	}}
 | 
	
		
			
				|  |  | +																>
 | 
	
		
			
				|  |  | +																	Clear files
 | 
	
		
			
				|  |  | +																</button>
 | 
	
		
			
				|  |  | +															</small>
 | 
	
		
			
				|  |  | +														</div>
 | 
	
		
			
				|  |  | +													</div>
 | 
	
		
			
				|  |  | +												);
 | 
	
		
			
				|  |  | +											}}
 | 
	
		
			
				|  |  | +										</DropzoneWrapper>
 | 
	
		
			
				|  |  | +									)}
 | 
	
		
			
				|  |  | +								</Field>
 | 
	
		
			
				|  |  | +								<ErrorMessage name="dokumen" component="div" className="form-text text-danger" />
 | 
	
		
			
				|  |  | +							</div>
 | 
	
		
			
				|  |  | +						</FormGroup>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +						<FormGroup row>
 | 
	
		
			
				|  |  | +							<div className="col-xl-10">
 | 
	
		
			
				|  |  | +								<button className="btn btn-sm btn-primary" type="submit" disabled={isSubmitting}>
 | 
	
		
			
				|  |  | +									Submit Laporan
 | 
	
		
			
				|  |  | +								</button>
 | 
	
		
			
				|  |  | +							</div>
 | 
	
		
			
				|  |  | +						</FormGroup>
 | 
	
		
			
				|  |  | +					</Form>
 | 
	
		
			
				|  |  | +				)}
 | 
	
		
			
				|  |  | +			</Formik>
 | 
	
		
			
				|  |  | +		);
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const mapStateToProps = (state) => ({ user: state.user, token: state.token });
 | 
	
		
			
				|  |  | +export default connect(mapStateToProps)(InputData);
 |