|
|
@@ -7,7 +7,27 @@ import { createLaporanPublic } from "@/actions/pelaporan";
|
|
|
import { notifLaporanBaru } from "@/actions/notifikasi";
|
|
|
import Select from "react-select";
|
|
|
import AsyncSelect from "react-select/async";
|
|
|
-import { Row, Col, FormGroup, Input, Card, CardBody, Button, CustomInput, Navbar, NavItem, NavLink, NavbarBrand, NavbarToggler, Nav, Collapse, Modal, ModalHeader, ModalBody, ModalFooter } from "reactstrap";
|
|
|
+import {
|
|
|
+ Row,
|
|
|
+ Col,
|
|
|
+ FormGroup,
|
|
|
+ Input,
|
|
|
+ Card,
|
|
|
+ CardBody,
|
|
|
+ Button,
|
|
|
+ CustomInput,
|
|
|
+ Navbar,
|
|
|
+ NavItem,
|
|
|
+ NavLink,
|
|
|
+ NavbarBrand,
|
|
|
+ NavbarToggler,
|
|
|
+ Nav,
|
|
|
+ Collapse,
|
|
|
+ Modal,
|
|
|
+ ModalHeader,
|
|
|
+ ModalBody,
|
|
|
+ ModalFooter,
|
|
|
+} from "reactstrap";
|
|
|
import Link from "next/link";
|
|
|
import ContentWrapper from "@/components/Layout/ContentWrapper";
|
|
|
import { createPublicUser } from "@/actions/user";
|
|
|
@@ -19,466 +39,638 @@ import swal from "sweetalert2";
|
|
|
import "react-toastify/dist/ReactToastify.css";
|
|
|
|
|
|
const checkIfFilesAreTooBig = (files) => {
|
|
|
- let valid = true;
|
|
|
- if (files) {
|
|
|
- files.map((file) => {
|
|
|
- if (file.size > 15 * 1024 * 1024) {
|
|
|
- valid = false;
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- return valid;
|
|
|
+ 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;
|
|
|
+ let valid = true;
|
|
|
+ if (files) {
|
|
|
+ files.map((file) => {
|
|
|
+ if (!["image/jpeg", "image/png"].includes(file.type)) {
|
|
|
+ valid = false;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ return valid;
|
|
|
};
|
|
|
|
|
|
const laporanSchema = Yup.object().shape({
|
|
|
- no_laporan: Yup.string().required(),
|
|
|
- no_hp: Yup.number().required("Wajib Diisi"),
|
|
|
- nama: Yup.string().notRequired(),
|
|
|
- setuju: Yup.boolean().isTrue("Harap diceklis"),
|
|
|
- alamat: Yup.string().min(3, "Minimal 3 huruf").max(200, "Maksimal 200 huruf").notRequired(),
|
|
|
- keterangan: Yup.string().min(3, "Minimal 3 huruf").max(200, "Maksimal 200 huruf").required(""),
|
|
|
- email: Yup.string().email().notRequired(),
|
|
|
- pelanggaran_id: Yup.array().min(1, "Minimal terdapat 1 jenis pelanggaran").required(""),
|
|
|
- pt_id: Yup.string().required(""),
|
|
|
- foto: Yup.array().notRequired().test("filesize", "Maksimal ukuran foto 15mb", checkIfFilesAreTooBig).test("type", "harus jpeg/png", checkIfFilesAreCorrectType),
|
|
|
- dokumen: Yup.array().min(1, " ").required().test("filesize", "Maksimal ukuran setiap dokumen 15mb", checkIfFilesAreTooBig),
|
|
|
- is_private: Yup.boolean().notRequired(),
|
|
|
+ no_laporan: Yup.string().required(),
|
|
|
+ no_hp: Yup.number().notRequired(),
|
|
|
+ nama: Yup.string().notRequired(),
|
|
|
+ setuju: Yup.boolean().isTrue("Harap diceklis"),
|
|
|
+ alamat: Yup.string()
|
|
|
+ .min(3, "Minimal 3 huruf")
|
|
|
+ .max(200, "Maksimal 200 huruf")
|
|
|
+ .notRequired(),
|
|
|
+ keterangan: Yup.string()
|
|
|
+ .min(3, "Minimal 3 huruf")
|
|
|
+ .max(200, "Maksimal 200 huruf")
|
|
|
+ .required(""),
|
|
|
+ email: Yup.string().email().notRequired(),
|
|
|
+ pelanggaran_id: Yup.array()
|
|
|
+ .min(1, "Minimal terdapat 1 jenis pelanggaran")
|
|
|
+ .required(""),
|
|
|
+ pt_id: Yup.string().required(""),
|
|
|
+ foto: Yup.array()
|
|
|
+ .notRequired()
|
|
|
+ .test("filesize", "Maksimal ukuran foto 15mb", checkIfFilesAreTooBig)
|
|
|
+ .test("type", "harus jpeg/png", checkIfFilesAreCorrectType),
|
|
|
+ dokumen: Yup.array()
|
|
|
+ .min(0, " ")
|
|
|
+ .notRequired()
|
|
|
+ .test(
|
|
|
+ "filesize",
|
|
|
+ "Maksimal ukuran setiap dokumen 15mb",
|
|
|
+ checkIfFilesAreTooBig
|
|
|
+ ),
|
|
|
+ is_private: Yup.boolean().notRequired(),
|
|
|
});
|
|
|
|
|
|
const loadOptions = (inputValue, callback) => {
|
|
|
- setTimeout(async () => {
|
|
|
- const pt = await ptPublic({ search: inputValue });
|
|
|
- const data = pt.data.map((e) => ({ value: e.id, label: e.nama, className: "State-ACT" }));
|
|
|
- callback(data);
|
|
|
- }, 1000);
|
|
|
+ setTimeout(async () => {
|
|
|
+ const pt = await ptPublic({ search: inputValue });
|
|
|
+ const data = pt.data.map((e) => ({
|
|
|
+ value: e.id,
|
|
|
+ label: e.nama,
|
|
|
+ className: "State-ACT",
|
|
|
+ }));
|
|
|
+ callback(data);
|
|
|
+ }, 1000);
|
|
|
};
|
|
|
|
|
|
const menu = [
|
|
|
- {
|
|
|
- title: "Home",
|
|
|
- path: "/app",
|
|
|
- },
|
|
|
- {
|
|
|
- title: "Buat Laporan",
|
|
|
- path: "/laporan/new",
|
|
|
- },
|
|
|
- {
|
|
|
- title: "Pemantauan",
|
|
|
- path: "/pemantauan",
|
|
|
- },
|
|
|
+ {
|
|
|
+ title: "Home",
|
|
|
+ path: "/app",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "Buat Laporan",
|
|
|
+ path: "/laporan/new",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "Pemantauan",
|
|
|
+ path: "/pemantauan",
|
|
|
+ },
|
|
|
];
|
|
|
const selectInstanceId = 1;
|
|
|
class App extends Component {
|
|
|
- constructor(props) {
|
|
|
- super(props);
|
|
|
- this.state = {
|
|
|
- isOpen: false,
|
|
|
- inputValue: "",
|
|
|
- pelaporanNumber: Math.floor(Date.now() * Math.random()),
|
|
|
- nama: "",
|
|
|
- alamat: "",
|
|
|
- no_hp: "",
|
|
|
- email: "",
|
|
|
- fileIdentitas: null,
|
|
|
- pelanggaran: [],
|
|
|
- selectedPerguruanTinggi: {},
|
|
|
- selectedJenis: [],
|
|
|
- keteranganLaporan: "",
|
|
|
- files: [],
|
|
|
- isPrivate: false,
|
|
|
- confirm: false,
|
|
|
- msgError: [],
|
|
|
- modal: false,
|
|
|
- user: {},
|
|
|
- kode: "",
|
|
|
- error: null,
|
|
|
- data: {},
|
|
|
- token: "",
|
|
|
- };
|
|
|
- }
|
|
|
+ constructor(props) {
|
|
|
+ super(props);
|
|
|
+ this.state = {
|
|
|
+ isOpen: false,
|
|
|
+ inputValue: "",
|
|
|
+ pelaporanNumber: Math.floor(Date.now() * Math.random()),
|
|
|
+ nama: "",
|
|
|
+ alamat: "",
|
|
|
+ no_hp: "",
|
|
|
+ email: "",
|
|
|
+ fileIdentitas: null,
|
|
|
+ pelanggaran: [],
|
|
|
+ selectedPerguruanTinggi: {},
|
|
|
+ selectedJenis: [],
|
|
|
+ keteranganLaporan: "",
|
|
|
+ files: [],
|
|
|
+ isPrivate: false,
|
|
|
+ confirm: false,
|
|
|
+ msgError: [],
|
|
|
+ modal: false,
|
|
|
+ user: {},
|
|
|
+ kode: "",
|
|
|
+ error: null,
|
|
|
+ data: {},
|
|
|
+ token: "",
|
|
|
+ };
|
|
|
+ }
|
|
|
|
|
|
- static getInitialProps = ({ pathname }) => ({ pathname });
|
|
|
+ static getInitialProps = ({ pathname }) => ({ pathname });
|
|
|
|
|
|
- componentDidMount = async () => {
|
|
|
- const pelanggaran = await getPelanggaranPublic();
|
|
|
- this.setState({ pelanggaran });
|
|
|
- };
|
|
|
+ componentDidMount = async () => {
|
|
|
+ const pelanggaran = await getPelanggaranPublic();
|
|
|
+ this.setState({ pelanggaran });
|
|
|
+ };
|
|
|
|
|
|
- toggleModal = () => {
|
|
|
- this.setState({ modal: !this.state.modal });
|
|
|
- };
|
|
|
+ toggleModal = () => {
|
|
|
+ this.setState({ modal: !this.state.modal });
|
|
|
+ };
|
|
|
|
|
|
- optionsJenisPelanggaran = (pelanggaran) => {
|
|
|
- return pelanggaran.data.map((e) => ({ value: e._id, label: e.pelanggaran, className: "State-ACT" }));
|
|
|
- };
|
|
|
+ optionsJenisPelanggaran = (pelanggaran) => {
|
|
|
+ return pelanggaran.data.map((e) => ({
|
|
|
+ value: e._id,
|
|
|
+ label: e.pelanggaran,
|
|
|
+ className: "State-ACT",
|
|
|
+ }));
|
|
|
+ };
|
|
|
|
|
|
- setKeteranganPelaporan = (e) => {
|
|
|
- this.setState({ keteranganLaporan: e.target.value });
|
|
|
- };
|
|
|
+ setKeteranganPelaporan = (e) => {
|
|
|
+ this.setState({ keteranganLaporan: e.target.value });
|
|
|
+ };
|
|
|
|
|
|
- handleChangeSelectJenis = (selectedJenis) => {
|
|
|
- this.setState({ selectedJenis });
|
|
|
- };
|
|
|
+ handleChangeSelectJenis = (selectedJenis) => {
|
|
|
+ this.setState({ selectedJenis });
|
|
|
+ };
|
|
|
|
|
|
- handleChangeSelectPerguruanTinggi = (selectedPerguruanTinggi) => {
|
|
|
- this.setState({ selectedPerguruanTinggi });
|
|
|
- };
|
|
|
+ handleChangeSelectPerguruanTinggi = (selectedPerguruanTinggi) => {
|
|
|
+ this.setState({ selectedPerguruanTinggi });
|
|
|
+ };
|
|
|
|
|
|
- handleInputChange = (newValue) => {
|
|
|
- const inputValue = newValue.replace(/\W/g, "");
|
|
|
- this.setState({ inputValue });
|
|
|
- return inputValue;
|
|
|
- };
|
|
|
+ handleInputChange = (newValue) => {
|
|
|
+ const inputValue = newValue.replace(/\W/g, "");
|
|
|
+ this.setState({ inputValue });
|
|
|
+ return inputValue;
|
|
|
+ };
|
|
|
|
|
|
- handleKirim = async (data, { resetForm }) => {
|
|
|
- const formdata = new FormData();
|
|
|
- formdata.append("no_laporan", data.no_laporan);
|
|
|
- formdata.append("pt_id", data.pt_id);
|
|
|
- formdata.append("nama", data.nama);
|
|
|
- formdata.append("email", data.email);
|
|
|
- formdata.append("no_hp", data.no_hp);
|
|
|
- formdata.append("alamat", data.alamat);
|
|
|
- formdata.append("is_private", data.is_private);
|
|
|
- formdata.append("keterangan", data.keterangan);
|
|
|
- formdata.append("pelanggaran_id", data.pelanggaran_id.join(","));
|
|
|
- formdata.append("foto", data.foto[0]);
|
|
|
+ handleKirim = async (data, { resetForm }) => {
|
|
|
+ const formdata = new FormData();
|
|
|
+ formdata.append("no_laporan", data.no_laporan);
|
|
|
+ formdata.append("pt_id", data.pt_id);
|
|
|
+ formdata.append("nama", data.nama);
|
|
|
+ formdata.append("email", data.email);
|
|
|
+ formdata.append("no_hp", data.no_hp);
|
|
|
+ formdata.append("alamat", data.alamat);
|
|
|
+ formdata.append("is_private", data.is_private);
|
|
|
+ formdata.append("keterangan", data.keterangan);
|
|
|
+ formdata.append("pelanggaran_id", data.pelanggaran_id.join(","));
|
|
|
+ formdata.append("foto", data.foto[0]);
|
|
|
|
|
|
- if (data.dokumen.length > 0) {
|
|
|
- Array.from(data.dokumen).forEach((e) => {
|
|
|
- formdata.append("dokumen", e);
|
|
|
- });
|
|
|
- }
|
|
|
+ if (data.dokumen.length > 0) {
|
|
|
+ Array.from(data.dokumen).forEach((e) => {
|
|
|
+ formdata.append("dokumen", e);
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
- const toastid = toast.loading("Please wait...");
|
|
|
- const success = await createLaporanPublic(formdata);
|
|
|
- if (!success) {
|
|
|
- swal.fire({
|
|
|
- title: 'Data tidak berhasil dikirim',
|
|
|
- icon: 'error',
|
|
|
- confirmButtonColor: '#6FB9DE',
|
|
|
- })
|
|
|
- } else {
|
|
|
- swal.fire({
|
|
|
- title: 'Data berhasil dikirim',
|
|
|
- icon: 'success',
|
|
|
- confirmButtonColor: '#6FB9DE',
|
|
|
- })
|
|
|
- Router.push("/laporan/new");
|
|
|
- }
|
|
|
- };
|
|
|
+ const toastid = toast.loading("Please wait...");
|
|
|
+ const success = await createLaporanPublic(formdata);
|
|
|
+ if (!success) {
|
|
|
+ swal.fire({
|
|
|
+ title: "Data tidak berhasil dikirim",
|
|
|
+ icon: "error",
|
|
|
+ confirmButtonColor: "#6FB9DE",
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ swal.fire({
|
|
|
+ title: "Data berhasil dikirim",
|
|
|
+ icon: "success",
|
|
|
+ confirmButtonColor: "#6FB9DE",
|
|
|
+ });
|
|
|
+ Router.push("/laporan/new");
|
|
|
+ }
|
|
|
+ };
|
|
|
|
|
|
- createLaporan = async (token, kode = "") => {
|
|
|
- const data = this.state.data;
|
|
|
- const formdata = new FormData();
|
|
|
- formdata.append("pt_id", data.pt_id);
|
|
|
- formdata.append("keterangan", data.keterangan);
|
|
|
- formdata.append("pelanggaran_id", data.pelanggaran_id.join(","));
|
|
|
- if (kode) {
|
|
|
- formdata.append("no_verifikasi", kode);
|
|
|
- }
|
|
|
- if (data.dokumen.length > 0) {
|
|
|
- Array.from(data.dokumen).forEach((e) => {
|
|
|
- formdata.append("dokumen", e);
|
|
|
- });
|
|
|
- }
|
|
|
+ createLaporan = async (token, kode = "") => {
|
|
|
+ const data = this.state.data;
|
|
|
+ const formdata = new FormData();
|
|
|
+ formdata.append("pt_id", data.pt_id);
|
|
|
+ formdata.append("keterangan", data.keterangan);
|
|
|
+ formdata.append("pelanggaran_id", data.pelanggaran_id.join(","));
|
|
|
+ if (kode) {
|
|
|
+ formdata.append("no_verifikasi", kode);
|
|
|
+ }
|
|
|
+ if (data.dokumen.length > 0) {
|
|
|
+ Array.from(data.dokumen).forEach((e) => {
|
|
|
+ formdata.append("dokumen", e);
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
- // const toastid = toast.loading("Please wait...");
|
|
|
- const success = await createLaporanPublic(token, formdata);
|
|
|
- if (!success) {
|
|
|
- // toast.update(toastid, { render: "All is not good", type: "error", isLoading: false, autoClose: true, closeButton: true });
|
|
|
- swal.fire({
|
|
|
- title: 'Kode verifikasi salah',
|
|
|
- icon: 'error',
|
|
|
- confirmButtonColor: '#6FB9DE',
|
|
|
- })
|
|
|
- this.setState({ error: "Kode verifikasi tidak valid" });
|
|
|
- } else {
|
|
|
- // toast.update(toastid, { render: "All is good", type: "success", isLoading: false, autoClose: true, closeButton: true });
|
|
|
- swal.fire({
|
|
|
- title: 'Data berhasil dikirim',
|
|
|
- icon: 'success',
|
|
|
- confirmButtonColor: '#6FB9DE',
|
|
|
- })
|
|
|
- this.toggleModal();
|
|
|
- Router.push("/laporan/new");
|
|
|
- }
|
|
|
- };
|
|
|
+ // const toastid = toast.loading("Please wait...");
|
|
|
+ const success = await createLaporanPublic(token, formdata);
|
|
|
+ if (!success) {
|
|
|
+ // toast.update(toastid, { render: "All is not good", type: "error", isLoading: false, autoClose: true, closeButton: true });
|
|
|
+ swal.fire({
|
|
|
+ title: "Kode verifikasi salah",
|
|
|
+ icon: "error",
|
|
|
+ confirmButtonColor: "#6FB9DE",
|
|
|
+ });
|
|
|
+ this.setState({ error: "Kode verifikasi tidak valid" });
|
|
|
+ } else {
|
|
|
+ // toast.update(toastid, { render: "All is good", type: "success", isLoading: false, autoClose: true, closeButton: true });
|
|
|
+ swal.fire({
|
|
|
+ title: "Data berhasil dikirim",
|
|
|
+ icon: "success",
|
|
|
+ confirmButtonColor: "#6FB9DE",
|
|
|
+ });
|
|
|
+ this.toggleModal();
|
|
|
+ Router.push("/laporan/new");
|
|
|
+ }
|
|
|
+ };
|
|
|
|
|
|
- createUser = async (data) => {
|
|
|
- const formdata = new FormData();
|
|
|
- formdata.append("no_laporan", data.no_laporan);
|
|
|
- formdata.append("pt_id", data.pt_id);
|
|
|
- if (data.nama) formdata.append("nama", data.nama);
|
|
|
- if (data.email) formdata.append("email", data.email);
|
|
|
- formdata.append("no_hp", data.no_hp);
|
|
|
- if (data.alamat) formdata.append("alamat", data.alamat);
|
|
|
- formdata.append("is_private", data.is_private);
|
|
|
- if (data.foto.length > 0) formdata.append("foto", data.foto[0]);
|
|
|
- return await createPublicUser(formdata);
|
|
|
- };
|
|
|
+ createUser = async (data) => {
|
|
|
+ const formdata = new FormData();
|
|
|
+ formdata.append("no_laporan", data.no_laporan);
|
|
|
+ formdata.append("pt_id", data.pt_id);
|
|
|
+ if (data.nama) formdata.append("nama", data.nama);
|
|
|
+ if (data.email) formdata.append("email", data.email);
|
|
|
+ formdata.append("no_hp", data.no_hp);
|
|
|
+ if (data.alamat) formdata.append("alamat", data.alamat);
|
|
|
+ formdata.append("is_private", data.is_private);
|
|
|
+ if (data.foto.length > 0) formdata.append("foto", data.foto[0]);
|
|
|
+ return await createPublicUser(formdata);
|
|
|
+ };
|
|
|
|
|
|
- render() {
|
|
|
- const { selectedJenis, pelanggaran } = this.state;
|
|
|
- return (
|
|
|
- <div>
|
|
|
- <ToastContainer />
|
|
|
- <Navbar className="navbar-color" expand="md" dark>
|
|
|
- <NavbarBrand href="/">
|
|
|
- <img className="width-133" src="/static/img/Logo-Sidali.png" alt="App Logo" />
|
|
|
- </NavbarBrand>
|
|
|
- <NavbarToggler onClick={this.toggleCollapse} />
|
|
|
- <Collapse isOpen={this.state.isOpen} navbar>
|
|
|
- <Nav className="ml-auto" navbar>
|
|
|
- {menu.map((e) => (
|
|
|
- <NavItem active={e.path === this.props.pathname ? true : false}>
|
|
|
- <Link href={e.path}>
|
|
|
- <NavLink style={{ cursor: "pointer" }}>{e.title}</NavLink>
|
|
|
- </Link>
|
|
|
- </NavItem>
|
|
|
- ))}
|
|
|
- </Nav>
|
|
|
- </Collapse>
|
|
|
- </Navbar>
|
|
|
- <ContentWrapper>
|
|
|
- <Row>
|
|
|
- <Col lg={8} className="block-center d-block ">
|
|
|
- <Card className="card-default">
|
|
|
- <CardBody>
|
|
|
- <Formik
|
|
|
- initialValues={{
|
|
|
- nama: "",
|
|
|
- no_hp: "",
|
|
|
- email: "",
|
|
|
- alamat: "",
|
|
|
- foto: [],
|
|
|
- no_laporan: moment(new Date()).format("DDMM") + "" + Math.floor(Math.random() * 1000000),
|
|
|
- pt_id: "",
|
|
|
- pelanggaran_id: "",
|
|
|
- keterangan: "",
|
|
|
- dokumen: [],
|
|
|
- setuju: false,
|
|
|
- is_private: false,
|
|
|
- }}
|
|
|
- validationSchema={laporanSchema}
|
|
|
- onSubmit={async (data) => {
|
|
|
- this.toggleModal();
|
|
|
- this.setState({ data, no_hp: data.no_hp });
|
|
|
- const user = await this.createUser(data);
|
|
|
- const token = user.data.token;
|
|
|
- this.setState({ user, token });
|
|
|
- }}
|
|
|
- >
|
|
|
- <Form className="form-horizontal">
|
|
|
- <div class="header-1">
|
|
|
- <h2 class="card-title-1">Identitas Pelapor</h2>
|
|
|
- </div>
|
|
|
- <FormGroup row></FormGroup>
|
|
|
- <FormGroup row>
|
|
|
- <label className="col-md-2 col-form-label">Nama Lengkap</label>
|
|
|
- <div className="col-md-10">
|
|
|
- <Field name="nama">{({ field }) => <Input type="text" {...field} />}</Field>
|
|
|
- <ErrorMessage name="nama" component="div" className="form-text text-danger" />
|
|
|
- </div>
|
|
|
- </FormGroup>
|
|
|
- <FormGroup row>
|
|
|
- <label className="col-md-2 col-form-label">
|
|
|
- Nomor Aktif<span className="star-color">*</span>
|
|
|
- </label>
|
|
|
- <div className="col-md-10">
|
|
|
- <Field name="no_hp">{({ field, form }) => <Input type="tel" {...field} />}</Field>
|
|
|
- <ErrorMessage name="no_hp" component="div" className="form-text text-danger" />
|
|
|
- </div>
|
|
|
- </FormGroup>
|
|
|
- <FormGroup row>
|
|
|
- <label className="col-md-2 col-form-label">Email</label>
|
|
|
- <div className="col-md-10">
|
|
|
- <Field name="email">{({ field }) => <Input type="email" {...field} />}</Field>
|
|
|
- <ErrorMessage name="email" component="div" className="form-text text-danger" />
|
|
|
- </div>
|
|
|
- </FormGroup>
|
|
|
- <FormGroup row>
|
|
|
- <label className="col-md-2 col-form-label">Alamat</label>
|
|
|
- <div className="col-md-10">
|
|
|
- <Field name="alamat">{({ field }) => <Input type="textarea" {...field} />}</Field>
|
|
|
- <ErrorMessage name="alamat" component="div" className="form-text text-danger" />
|
|
|
- </div>
|
|
|
- </FormGroup>
|
|
|
- <FormGroup row>
|
|
|
- <label className="col-md-2 col-form-label">Foto Kartu Identitas</label>
|
|
|
- <div className="col-md-10">
|
|
|
- <Field name="foto">{({ field, form }) => <Input type="file" onChange={(e) => form.setFieldValue(field.name, Array.from(e.currentTarget.files))} />}</Field>
|
|
|
- <ErrorMessage name="foto" component="div" className="form-text text-danger" />
|
|
|
- <p className="mrgn-top-5">
|
|
|
- Ukuran setiap dokumen maksimal 15mb
|
|
|
- </p>
|
|
|
- </div>
|
|
|
- <div className="col-xl-10">
|
|
|
- <div className="checkbox c-checkbox">
|
|
|
- <label>
|
|
|
- <Field name="is_private">{({ field }) => <Input type="checkbox" {...field} />}</Field>
|
|
|
- <span className="fa fa-check"></span>
|
|
|
- <text>Klik jika ingin merahasiakan identitas anda</text>
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </FormGroup>
|
|
|
- <div class="header-1">
|
|
|
- <h2 class="card-title-1">Detail Laporan<span className="font-20">(wajib diisi)</span></h2>
|
|
|
- </div>
|
|
|
- {/* <p className="lead bb">Detail Laporan</p> */}
|
|
|
- <FormGroup row>
|
|
|
- <label className="col-md-2 col-form-label">Nomor Pelaporan</label>
|
|
|
- <div className="col-md-10">
|
|
|
- <Field name="no_laporan">{({ field }) => <Input disabled type="text" {...field} />}</Field>
|
|
|
- <ErrorMessage name="no_laporan" component="div" className="form-text text-danger" />
|
|
|
- </div>
|
|
|
- </FormGroup>
|
|
|
- <FormGroup row>
|
|
|
- <label className="col-md-2 col-form-label">
|
|
|
- Perguruan Tinggi yang Dilaporkan<span className="star-color"></span>
|
|
|
- </label>
|
|
|
- <div className="col-md-10">
|
|
|
- <Field name="pt_id">
|
|
|
- {({ field, form }) => (
|
|
|
- <AsyncSelect
|
|
|
- cacheOptions
|
|
|
- loadOptions={loadOptions}
|
|
|
- defaultOptions
|
|
|
- onChange={(e) => {
|
|
|
- this.handleChangeSelectPerguruanTinggi(e);
|
|
|
- form.setFieldValue(field.name, e.value);
|
|
|
- }}
|
|
|
- onInputChange={this.handleInputChange}
|
|
|
- />
|
|
|
- )}
|
|
|
- </Field>
|
|
|
- <ErrorMessage name="pt_id" component="div" className="form-text text-danger" />
|
|
|
- </div>
|
|
|
- </FormGroup>
|
|
|
- <FormGroup row>
|
|
|
- <label className="col-md-2 col-form-label">
|
|
|
- Jenis Pelanggaran<span className="star-color"></span>
|
|
|
- </label>
|
|
|
- <div className="col-md-10">
|
|
|
- <Field name="pelanggaran_id">
|
|
|
- {({ field, form }) => (
|
|
|
- <Select
|
|
|
- instanceId={selectInstanceId + 1}
|
|
|
- isMulti
|
|
|
- value={selectedJenis}
|
|
|
- onChange={(e) => {
|
|
|
- this.handleChangeSelectJenis(e);
|
|
|
- form.setFieldValue(
|
|
|
- field.name,
|
|
|
- e.map((e) => e.value)
|
|
|
- );
|
|
|
- }}
|
|
|
- options={pelanggaran.data ? this.optionsJenisPelanggaran(pelanggaran) : []}
|
|
|
- required
|
|
|
- />
|
|
|
- )}
|
|
|
- </Field>
|
|
|
- <ErrorMessage name="pelanggaran_id" component="div" className="form-text text-danger" />
|
|
|
- </div>
|
|
|
- </FormGroup>
|
|
|
- <FormGroup row>
|
|
|
- <label className="col-md-2 col-form-label">
|
|
|
- Keterangan Laporan<span className="star-color"></span>
|
|
|
- </label>
|
|
|
- <div className="col-md-10">
|
|
|
- <Field name="keterangan">{({ field }) => <Input type="textarea" {...field} />}</Field>
|
|
|
- <ErrorMessage name="keterangan" component="div" className="form-text text-danger" />
|
|
|
- </div>
|
|
|
- </FormGroup>
|
|
|
- <FormGroup row>
|
|
|
- <label className="col-md-2 col-form-label">
|
|
|
- File Pendukung
|
|
|
- </label>
|
|
|
- <div className="col-md-10">
|
|
|
- <Field name="dokumen">{({ field, form }) => <Input type="file" multiple onChange={(e) => form.setFieldValue(field.name, Array.from(e.currentTarget.files))} />}</Field>
|
|
|
- <ErrorMessage name="dokumen" component="div" className="form-text text-danger" />
|
|
|
- <p className="mrgn-top-5">
|
|
|
- Ukuran setiap dokumen maksimal 15mb
|
|
|
- </p>
|
|
|
- </div>
|
|
|
- </FormGroup>
|
|
|
- <FormGroup row>
|
|
|
- <div className="col-xl-10">
|
|
|
- <div className="checkbox c-checkbox">
|
|
|
- <label>
|
|
|
- <Field name="setuju">{({ field }) => <Input type="checkbox" {...field} />}</Field>
|
|
|
- <span className="fa fa-check"></span>
|
|
|
- <text>Klik jika data yang anda laporkan sudah benar</text>
|
|
|
- <ErrorMessage name="setuju" component="div" className="form-text text-danger" />
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </FormGroup>
|
|
|
- <FormGroup row>
|
|
|
- <div className="posisi-btn-1 btn-radius">
|
|
|
- <Button className="button-kirimlaporan" color type="submit">
|
|
|
- <h3 className="text-kirimlaporan font-color-white">Kirim Laporan</h3>
|
|
|
- </Button>
|
|
|
- </div>
|
|
|
- </FormGroup>
|
|
|
- </Form>
|
|
|
- </Formik>
|
|
|
- </CardBody>
|
|
|
- </Card>
|
|
|
- </Col>
|
|
|
- </Row>
|
|
|
- <Modal isOpen={this.state.modal}>
|
|
|
- <form className="form-horizontal">
|
|
|
- <ModalBody>
|
|
|
- <FormGroup>
|
|
|
- <label>Masukkan Kode Verifikasi</label>
|
|
|
- <div>
|
|
|
- <Input onChange={(e) => this.setState({ kode: e.target.value })} type="text" />
|
|
|
- </div>
|
|
|
- <p>*Kode verifikasi terkirim ke nomor WA {this.state.no_hp}</p>
|
|
|
- {this.state.error && <div className="form-text text-danger">{this.state.error}</div>}
|
|
|
- </FormGroup>
|
|
|
- </ModalBody>
|
|
|
- <ModalFooter>
|
|
|
- <Button
|
|
|
- color="info"
|
|
|
- onClick={async () => {
|
|
|
- await this.createLaporan(this.state.token);
|
|
|
- }}
|
|
|
- >
|
|
|
- Buat Laporan Tanpa Kode Verifikasi
|
|
|
- </Button>
|
|
|
- <Button
|
|
|
- color="primary"
|
|
|
- onClick={async () => {
|
|
|
- if (this.state.kode) {
|
|
|
- await this.createLaporan(this.state.token, this.state.kode);
|
|
|
- } else {
|
|
|
- this.setState({ error: "Kode verifikasi harus diisi" });
|
|
|
- }
|
|
|
- }}
|
|
|
- >
|
|
|
- Kirim
|
|
|
- </Button>
|
|
|
- </ModalFooter>
|
|
|
- </form>
|
|
|
- </Modal>
|
|
|
- </ContentWrapper>
|
|
|
- </div >
|
|
|
- );
|
|
|
- }
|
|
|
+ render() {
|
|
|
+ const { selectedJenis, pelanggaran } = this.state;
|
|
|
+ return (
|
|
|
+ <div>
|
|
|
+ <ToastContainer />
|
|
|
+ <Navbar className="navbar-color" expand="md" dark>
|
|
|
+ <NavbarBrand href="/">
|
|
|
+ <img
|
|
|
+ className="width-133"
|
|
|
+ src="/static/img/Logo-Sidali.png"
|
|
|
+ alt="App Logo"
|
|
|
+ />
|
|
|
+ </NavbarBrand>
|
|
|
+ <NavbarToggler onClick={this.toggleCollapse} />
|
|
|
+ <Collapse isOpen={this.state.isOpen} navbar>
|
|
|
+ <Nav className="ml-auto" navbar>
|
|
|
+ {menu.map((e) => (
|
|
|
+ <NavItem active={e.path === this.props.pathname ? true : false}>
|
|
|
+ <Link href={e.path}>
|
|
|
+ <NavLink style={{ cursor: "pointer" }}>{e.title}</NavLink>
|
|
|
+ </Link>
|
|
|
+ </NavItem>
|
|
|
+ ))}
|
|
|
+ </Nav>
|
|
|
+ </Collapse>
|
|
|
+ </Navbar>
|
|
|
+ <ContentWrapper>
|
|
|
+ <Row>
|
|
|
+ <Col lg={8} className="block-center d-block ">
|
|
|
+ <Card className="card-default">
|
|
|
+ <CardBody>
|
|
|
+ <Formik
|
|
|
+ initialValues={{
|
|
|
+ nama: "",
|
|
|
+ no_hp: "",
|
|
|
+ email: "",
|
|
|
+ alamat: "",
|
|
|
+ foto: [],
|
|
|
+ no_laporan:
|
|
|
+ moment(new Date()).format("DDMM") +
|
|
|
+ "" +
|
|
|
+ Math.floor(Math.random() * 1000000),
|
|
|
+ pt_id: "",
|
|
|
+ pelanggaran_id: "",
|
|
|
+ keterangan: "",
|
|
|
+ dokumen: [],
|
|
|
+ setuju: false,
|
|
|
+ is_private: false,
|
|
|
+ }}
|
|
|
+ validationSchema={laporanSchema}
|
|
|
+ onSubmit={async (data) => {
|
|
|
+ this.toggleModal();
|
|
|
+ this.setState({ data, no_hp: data.no_hp });
|
|
|
+ const user = await this.createUser(data);
|
|
|
+ const token = user.data.token;
|
|
|
+ this.setState({ user, token });
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <Form className="form-horizontal">
|
|
|
+ <div class="header-1">
|
|
|
+ <h2 class="card-title-1">Identitas Pelapor</h2>
|
|
|
+ </div>
|
|
|
+ <FormGroup row></FormGroup>
|
|
|
+ <FormGroup row>
|
|
|
+ <label className="col-md-2 col-form-label">
|
|
|
+ Nama Lengkap
|
|
|
+ </label>
|
|
|
+ <div className="col-md-10">
|
|
|
+ <Field name="nama">
|
|
|
+ {({ field }) => <Input type="text" {...field} />}
|
|
|
+ </Field>
|
|
|
+ <ErrorMessage
|
|
|
+ name="nama"
|
|
|
+ component="div"
|
|
|
+ className="form-text text-danger"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </FormGroup>
|
|
|
+ <FormGroup row>
|
|
|
+ <label className="col-md-2 col-form-label">
|
|
|
+ Nomor Aktif
|
|
|
+ <span className="star-color">
|
|
|
+ {" "}
|
|
|
+ (opsional)
|
|
|
+ </span>
|
|
|
+ </label>
|
|
|
+ <div className="col-md-10">
|
|
|
+ <Field name="no_hp">
|
|
|
+ {({ field, form }) => (
|
|
|
+ <Input type="tel" {...field} />
|
|
|
+ )}
|
|
|
+ </Field>
|
|
|
+ <ErrorMessage
|
|
|
+ name="no_hp"
|
|
|
+ component="div"
|
|
|
+ className="form-text text-danger"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </FormGroup>
|
|
|
+ <FormGroup row>
|
|
|
+ <label className="col-md-2 col-form-label">Email</label>
|
|
|
+ <div className="col-md-10">
|
|
|
+ <Field name="email">
|
|
|
+ {({ field }) => <Input type="email" {...field} />}
|
|
|
+ </Field>
|
|
|
+ <ErrorMessage
|
|
|
+ name="email"
|
|
|
+ component="div"
|
|
|
+ className="form-text text-danger"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </FormGroup>
|
|
|
+ <FormGroup row>
|
|
|
+ <label className="col-md-2 col-form-label">
|
|
|
+ Alamat
|
|
|
+ </label>
|
|
|
+ <div className="col-md-10">
|
|
|
+ <Field name="alamat">
|
|
|
+ {({ field }) => (
|
|
|
+ <Input type="textarea" {...field} />
|
|
|
+ )}
|
|
|
+ </Field>
|
|
|
+ <ErrorMessage
|
|
|
+ name="alamat"
|
|
|
+ component="div"
|
|
|
+ className="form-text text-danger"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </FormGroup>
|
|
|
+ <FormGroup row>
|
|
|
+ <label className="col-md-2 col-form-label">
|
|
|
+ Foto Kartu Identitas
|
|
|
+ </label>
|
|
|
+ <div className="col-md-10">
|
|
|
+ <Field name="foto">
|
|
|
+ {({ field, form }) => (
|
|
|
+ <Input
|
|
|
+ type="file"
|
|
|
+ onChange={(e) =>
|
|
|
+ form.setFieldValue(
|
|
|
+ field.name,
|
|
|
+ Array.from(e.currentTarget.files)
|
|
|
+ )
|
|
|
+ }
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ </Field>
|
|
|
+ <ErrorMessage
|
|
|
+ name="foto"
|
|
|
+ component="div"
|
|
|
+ className="form-text text-danger"
|
|
|
+ />
|
|
|
+ <p className="mrgn-top-5">
|
|
|
+ Ukuran setiap dokumen maksimal 15mb
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+ <div className="col-xl-10">
|
|
|
+ <div className="checkbox c-checkbox">
|
|
|
+ <label>
|
|
|
+ <Field name="is_private">
|
|
|
+ {({ field }) => (
|
|
|
+ <Input type="checkbox" {...field} />
|
|
|
+ )}
|
|
|
+ </Field>
|
|
|
+ <span className="fa fa-check"></span>
|
|
|
+ <text>
|
|
|
+ Klik jika ingin merahasiakan identitas anda
|
|
|
+ </text>
|
|
|
+ </label>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </FormGroup>
|
|
|
+ <div class="header-1">
|
|
|
+ <h2 class="card-title-1">
|
|
|
+ Detail Laporan
|
|
|
+ {/* <span className="font-20">(wajib diisi)</span> */}
|
|
|
+ </h2>
|
|
|
+ </div>
|
|
|
+ {/* <p className="lead bb">Detail Laporan</p> */}
|
|
|
+ <FormGroup row>
|
|
|
+ <label className="col-md-2 col-form-label">
|
|
|
+ Nomor Pelaporan
|
|
|
+ </label>
|
|
|
+ <div className="col-md-10">
|
|
|
+ <Field name="no_laporan">
|
|
|
+ {({ field }) => (
|
|
|
+ <Input disabled type="text" {...field} />
|
|
|
+ )}
|
|
|
+ </Field>
|
|
|
+ <ErrorMessage
|
|
|
+ name="no_laporan"
|
|
|
+ component="div"
|
|
|
+ className="form-text text-danger"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </FormGroup>
|
|
|
+ <FormGroup row>
|
|
|
+ <label className="col-md-2 col-form-label">
|
|
|
+ Perguruan Tinggi yang Dilaporkan
|
|
|
+ <span className="star-color"></span>
|
|
|
+ </label>
|
|
|
+ <div className="col-md-10">
|
|
|
+ <Field name="pt_id">
|
|
|
+ {({ field, form }) => (
|
|
|
+ <AsyncSelect
|
|
|
+ cacheOptions
|
|
|
+ loadOptions={loadOptions}
|
|
|
+ defaultOptions
|
|
|
+ onChange={(e) => {
|
|
|
+ this.handleChangeSelectPerguruanTinggi(e);
|
|
|
+ form.setFieldValue(field.name, e.value);
|
|
|
+ }}
|
|
|
+ onInputChange={this.handleInputChange}
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ </Field>
|
|
|
+ <ErrorMessage
|
|
|
+ name="pt_id"
|
|
|
+ component="div"
|
|
|
+ className="form-text text-danger"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </FormGroup>
|
|
|
+ <FormGroup row>
|
|
|
+ <label className="col-md-2 col-form-label">
|
|
|
+ Jenis Pelanggaran<span className="star-color"></span>
|
|
|
+ </label>
|
|
|
+ <div className="col-md-10">
|
|
|
+ <Field name="pelanggaran_id">
|
|
|
+ {({ field, form }) => (
|
|
|
+ <Select
|
|
|
+ instanceId={selectInstanceId + 1}
|
|
|
+ isMulti
|
|
|
+ value={selectedJenis}
|
|
|
+ onChange={(e) => {
|
|
|
+ this.handleChangeSelectJenis(e);
|
|
|
+ form.setFieldValue(
|
|
|
+ field.name,
|
|
|
+ e.map((e) => e.value)
|
|
|
+ );
|
|
|
+ }}
|
|
|
+ options={
|
|
|
+ pelanggaran.data
|
|
|
+ ? this.optionsJenisPelanggaran(pelanggaran)
|
|
|
+ : []
|
|
|
+ }
|
|
|
+ required
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ </Field>
|
|
|
+ <ErrorMessage
|
|
|
+ name="pelanggaran_id"
|
|
|
+ component="div"
|
|
|
+ className="form-text text-danger"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </FormGroup>
|
|
|
+ <FormGroup row>
|
|
|
+ <label className="col-md-2 col-form-label">
|
|
|
+ Keterangan Laporan<span className="star-color"></span>
|
|
|
+ </label>
|
|
|
+ <div className="col-md-10">
|
|
|
+ <Field name="keterangan">
|
|
|
+ {({ field }) => (
|
|
|
+ <Input type="textarea" {...field} />
|
|
|
+ )}
|
|
|
+ </Field>
|
|
|
+ <ErrorMessage
|
|
|
+ name="keterangan"
|
|
|
+ component="div"
|
|
|
+ className="form-text text-danger"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </FormGroup>
|
|
|
+ <FormGroup row>
|
|
|
+ <label className="col-md-2 col-form-label">
|
|
|
+ File Pendukung
|
|
|
+ </label>
|
|
|
+ <div className="col-md-10">
|
|
|
+ <Field name="dokumen">
|
|
|
+ {({ field, form }) => (
|
|
|
+ <Input
|
|
|
+ type="file"
|
|
|
+ multiple
|
|
|
+ onChange={(e) =>
|
|
|
+ form.setFieldValue(
|
|
|
+ field.name,
|
|
|
+ Array.from(e.currentTarget.files)
|
|
|
+ )
|
|
|
+ }
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ </Field>
|
|
|
+ <ErrorMessage
|
|
|
+ name="dokumen"
|
|
|
+ component="div"
|
|
|
+ className="form-text text-danger"
|
|
|
+ />
|
|
|
+ <p className="mrgn-top-5">
|
|
|
+ Ukuran setiap dokumen maksimal 15mb
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+ </FormGroup>
|
|
|
+ <FormGroup row>
|
|
|
+ <div className="col-xl-10">
|
|
|
+ <div className="checkbox c-checkbox">
|
|
|
+ <label>
|
|
|
+ <Field name="setuju">
|
|
|
+ {({ field }) => (
|
|
|
+ <Input type="checkbox" {...field} />
|
|
|
+ )}
|
|
|
+ </Field>
|
|
|
+ <span className="fa fa-check"></span>
|
|
|
+ <text>
|
|
|
+ Klik jika data yang anda laporkan sudah benar
|
|
|
+ </text>
|
|
|
+ <ErrorMessage
|
|
|
+ name="setuju"
|
|
|
+ component="div"
|
|
|
+ className="form-text text-danger"
|
|
|
+ />
|
|
|
+ </label>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </FormGroup>
|
|
|
+ <FormGroup row>
|
|
|
+ <div className="posisi-btn-1 btn-radius">
|
|
|
+ <Button
|
|
|
+ className="button-kirimlaporan"
|
|
|
+ color
|
|
|
+ type="submit"
|
|
|
+ >
|
|
|
+ <h3 className="text-kirimlaporan font-color-white">
|
|
|
+ Kirim Laporan
|
|
|
+ </h3>
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+ </FormGroup>
|
|
|
+ </Form>
|
|
|
+ </Formik>
|
|
|
+ </CardBody>
|
|
|
+ </Card>
|
|
|
+ </Col>
|
|
|
+ </Row>
|
|
|
+ <Modal isOpen={this.state.modal}>
|
|
|
+ <form className="form-horizontal">
|
|
|
+ <ModalBody>
|
|
|
+ <FormGroup>
|
|
|
+ <label>Masukkan Kode Verifikasi</label>
|
|
|
+ <div>
|
|
|
+ <Input
|
|
|
+ onChange={(e) => this.setState({ kode: e.target.value })}
|
|
|
+ type="text"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <p>
|
|
|
+ *Kode verifikasi terkirim ke nomor WA {this.state.no_hp}
|
|
|
+ </p>
|
|
|
+ {this.state.error && (
|
|
|
+ <div className="form-text text-danger">
|
|
|
+ {this.state.error}
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ </FormGroup>
|
|
|
+ </ModalBody>
|
|
|
+ <ModalFooter>
|
|
|
+ <Button
|
|
|
+ color="info"
|
|
|
+ onClick={async () => {
|
|
|
+ await this.createLaporan(this.state.token);
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ Buat Laporan Tanpa Kode Verifikasi
|
|
|
+ </Button>
|
|
|
+ <Button
|
|
|
+ color="primary"
|
|
|
+ onClick={async () => {
|
|
|
+ if (this.state.kode) {
|
|
|
+ await this.createLaporan(
|
|
|
+ this.state.token,
|
|
|
+ this.state.kode
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ this.setState({ error: "Kode verifikasi harus diisi" });
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ Kirim
|
|
|
+ </Button>
|
|
|
+ </ModalFooter>
|
|
|
+ </form>
|
|
|
+ </Modal>
|
|
|
+ </ContentWrapper>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
App.Layout = BasePage;
|