Browse Source

Merge branch 'master' of https://source.sidali.vertizoncode.com/andifebri/PTB-fe

andi 2 years ago
parent
commit
3d97086a6b
37 changed files with 1279 additions and 269 deletions
  1. 35 0
      actions/autosave.js
  2. 10 1
      components/Delegasi/CaseProgress.js
  3. 1 1
      components/Layout/Footer.js
  4. 6 0
      components/Layout/MenuLLDIKTI.js
  5. 9 3
      components/Main/Login.js
  6. 22 9
      components/NaikSanksi/InputTanggal.js
  7. 20 7
      components/PT/JawabanKeberatan/ModalPermohonan.js
  8. 20 7
      components/PT/Keberatan/ModalPermohonan.js
  9. 28 13
      components/Pelaporan/InputData.js
  10. 19 8
      components/Pemeriksaan/InputEvaluasi.js
  11. 1 2
      components/Penjadwalan/CaseProgress.js
  12. 19 6
      components/PerpanjanganSanksi/InputTanggal.js
  13. 6 8
      components/PerpanjanganSanksi/TableLaporan.js
  14. 20 6
      components/RekomendasiDelegasi/InputRekomendasi.js
  15. 46 0
      components/Sanksi/BeritaAcara_A.js
  16. 25 0
      components/Sanksi/Ringkasan.js
  17. 260 0
      components/Sanksi/SuratBA.js
  18. 40 2
      components/Sanksi/TablePenetapanSanksi.js
  19. 0 77
      components/Sanksi/TmtDate.js
  20. 105 15
      components/Sanksi/UploadSurat.js
  21. 21 8
      components/TurunSanksi/InputTanggal.js
  22. 39 0
      package-lock.json
  23. 2 0
      package.json
  24. 1 1
      pages/app/index.js
  25. 38 1
      pages/app/laporan-delegasi/index.js
  26. 19 11
      pages/app/pelaporan/index.js
  27. 3 2
      pages/app/pemantauan/timeline.js
  28. 24 2
      pages/app/pemeriksaan/index.js
  29. 20 2
      pages/app/penjadwalan/index.js
  30. 1 1
      pages/app/perpanjangan-sanksi/index.js
  31. 20 2
      pages/app/sanksi/index.js
  32. 63 12
      pages/app/sanksi/proses.js
  33. 36 6
      pages/app/tuntas/index.js
  34. 94 25
      styles/app/common/bootstrap-reset.scss
  35. 16 0
      styles/bootstrap/_buttons.scss
  36. 50 29
      styles/bootstrap/_card.scss
  37. 140 2
      styles/bootstrap/_progress.scss

+ 35 - 0
actions/autosave.js

@@ -0,0 +1,35 @@
+import axios from "@/config/axios";
+
+export const getAutoSave = async ({ token, laporan, sanksi, id }) => {
+    try {
+        let url = "";
+        if (laporan) {
+            url += `/auto/save/${id}?laporan=true`;
+        }
+        if (sanksi) {
+            url += `/auto/save/${id}?sanksi=true`;
+        }
+        const res = await axios.get(url, { headers: { Authorization: token } });
+        return res.data;
+    } catch (error) {
+        console.log("error", error);
+        return false;
+    }
+};
+
+export const inputAutoSave = async ({ token, laporan, sanksi, id, data }) => {
+    try {
+        let url = "";
+        if (laporan) {
+            url += `/auto/save/${id}?laporan=true`;
+        }
+        if (sanksi) {
+            url += `/auto/save/${id}?sanksi=true`;
+        }
+        const res = await axios.post(url, data, { headers: { Authorization: token } });
+        return res.data;
+    } catch (error) {
+        console.log("error", error);
+        return false;
+    }
+};

+ 10 - 1
components/Delegasi/CaseProgress.js

@@ -9,7 +9,7 @@ import Datatable from "@/components/Tables/Datatable";
 import MorrisChart from "@/components/Charts//Morris";
 import Dropdown from 'react-bootstrap/Dropdown';
 
-function CaseProgress({ data, nextButton, prevButton, tahun, excel }) {
+function CaseProgress({ data, nextButton, prevButton, tahun, excel, excelSemua, excelMenu }) {
 	const ChartPie = {
 		data: [
 			{
@@ -117,6 +117,15 @@ function CaseProgress({ data, nextButton, prevButton, tahun, excel }) {
 						<img src="/static/img/next.png"></img>
 					</Button>
 					<b className="text-tahun">Tahun {tahun} </b>
+					<Dropdown className="float-right">
+						<Dropdown.Toggle variant="success" id="dropdown-basic">
+							Unduh
+						</Dropdown.Toggle>
+						<Dropdown.Menu>
+							<Dropdown.Item onClick={excelMenu}>Unduh dokumen pelaporan</Dropdown.Item>
+							<Dropdown.Item onClick={excelSemua}>Unduh dokumen semua menu</Dropdown.Item>
+						</Dropdown.Menu>
+					</Dropdown>
 					{/* <Button className="float-right button-hidden icon-eksport" type="submit" onClick={excel}>
 						<img src="/static/img/eksport.png"></img>
 					</Button> */}

+ 1 - 1
components/Layout/Footer.js

@@ -7,7 +7,7 @@ class Footer extends Component {
         return (
             <footer className="footer-container">
                 <span>Sidali Dikti &copy; {year}</span>
-                <span className=' float-right'>Version 2.1 ~ 1.88</span>
+                <span className=' float-right'>Version 2.2 ~ 1.96</span>
             </footer>
         );
     }

+ 6 - 0
components/Layout/MenuLLDIKTI.js

@@ -43,6 +43,12 @@ const Menu = [
 		icon: "icon-hourglass",
 		translate: "sidebar.nav.KEBERATAN",
 	},
+	{
+		name: "Banding",
+		path: "/app/banding",
+		icon: "icon-directions",
+		translate: "sidebar.nav.BANDING",
+	},
 	{
 		name: "Pemantauan Perbaikan",
 		path: "/app/perbaikan",

+ 9 - 3
components/Main/Login.js

@@ -118,7 +118,13 @@ class Login extends Component {
             ></img>
             <b>Login Menggunakan Akun PDDIKTI </b>
           </h5>
-          {this.state.error}
+          {this.state.error && <div style={{
+            backgroundColor: '#f8d7da',
+            padding: '5px',
+            borderRadius: '3px'
+          }}>
+            <span className=" text-bold">{this.state.error}</span>
+          </div>}
           <form onSubmit={this.onSubmit} method="post" name="formLogin">
             <div className="form-group">
               <label className="col-form-label">
@@ -133,7 +139,7 @@ class Login extends Component {
                 value={this.state.formLogin.username}
               />
               {this.hasError("formLogin", "username", "required") && (
-                <span className="invalid-feedback">Field is required</span>
+                <span className="invalid-feedback">Wajib diisi</span>
               )}
             </div>
             <div className="form-group">
@@ -149,7 +155,7 @@ class Login extends Component {
                 data-validate='["required"]'
                 value={this.state.formLogin.password}
               />
-              <span className="invalid-feedback">Field is required</span>
+              <span className="invalid-feedback">Wajib diisi</span>
             </div>
             {/* <div className="required">* Required fields</div>
 						<span>Login Menggunakan Akun PDDIKTI</span> */}

+ 22 - 9
components/NaikSanksi/InputTanggal.js

@@ -1,5 +1,5 @@
 import React, { Component } from "react";
-import { Row, Col, Card, CardBody, FormGroup, Input, Button, Modal, ModalHeader, ModalBody, ModalFooter, CardHeader, CardTitle } from "reactstrap";
+import { Row, Col, Card, CardBody, FormGroup, Input, Button, Progress } from "reactstrap";
 import { toast } from "react-toastify";
 import { Formik, Form, Field, ErrorMessage } from "formik";
 import * as Yup from "yup";
@@ -46,7 +46,7 @@ const rekomendasiSchema = Yup.object().shape({
     no_sanksi: Yup.string().required("Wajib isi Nomor Sanksi"),
     keterangan: Yup.string().min(3, "Minimal 3 Huruf").max(200).required("Wajib isi keterangan"),
     from_date: Yup.date().required("Wajib diisi"),
-    to_date: Yup.date().required("Wajib diisi"),
+    to_date: Yup.date().notRequired("Wajib diisi"),
     sanksi: Yup.array().required("Wajib isi pelanggaran"),
     dokumen: Yup.array().required("Wajib diisi").test("filesize", "Maksimal ukuran dokumen 15mb", checkIfFilesAreTooBig),
 });
@@ -173,11 +173,18 @@ class InputTanggal extends Component {
     };
     render() {
         const { files } = this.state;
-
+        const removeFile = file => () => {
+            const newFiles = [...files]
+            newFiles.splice(newFiles.indexOf(file), 1)
+            this.setState({
+                files: newFiles,
+            });
+        }
         const thumbs = files.map((file, index) => (
-            <div md={3} key={index}>
-                <span className="text-left">{index + 1}.{file.name}</span>
-            </div>
+            <p>
+                <em className="far fa-file" />&nbsp;&nbsp;{file.name}
+                <button className="bg-transparent button-transparent border-0 fas fa-trash text-danger float-right" onClick={removeFile(file)} />
+            </p>
         ));
         return (
             <Card className="card-default">
@@ -198,9 +205,9 @@ class InputTanggal extends Component {
                         {() => (
                             <Form className="form-horizontal">
                                 <FormGroup row>
-                                    <label className="col-md-2 col-form-label">Nomor Sanksi</label>
+                                    <label className="col-md-2 col-form-label">Nomor Surat</label>
                                     <div className="col-md-10">
-                                        <Field name="no_sanksi">{({ field }) => <Input type="textarea" placeholder="Nomor Sanksi" {...field} />}</Field>
+                                        <Field name="no_sanksi">{({ field }) => <Input type="textarea" placeholder="Nomor Surat" {...field} />}</Field>
                                         <ErrorMessage name="no_sanksi" component="div" className="form-text text-danger" />
                                     </div>
                                 </FormGroup>
@@ -345,7 +352,10 @@ class InputTanggal extends Component {
                                                                 <input {...getInputProps()} />
                                                                 <div className="dropzone-previews flex">
                                                                     <div className="dropzone-style-1">
-                                                                        <div className="center-ver-hor dropzone-previews flex">{this.state.files.length > 0 ? <Row><span className="text-left">{thumbs}</span></Row> :
+                                                                        <div className="center-ver-hor dropzone-previews flex">{this.state.files.length > 0 ?
+                                                                            <div className="text-center fa-2x icon-cloud-upload mr-2 ">
+                                                                                <h5 className="text-center dz-default dz-message">Klik untuk tambah file</h5>
+                                                                            </div> :
                                                                             <div className="text-center fa-2x icon-cloud-upload mr-2 ">
                                                                                 <h5 className="text-center dz-default dz-message">Upload dokumen rekomendasi delegasi</h5>
                                                                             </div>
@@ -373,6 +383,9 @@ class InputTanggal extends Component {
                                                 </DropzoneWrapper>
                                             )}
                                         </Field>
+                                        <div>
+                                            {thumbs}
+                                        </div>
                                     </div>
                                 </FormGroup>
                                 <FormGroup row>

+ 20 - 7
components/PT/JawabanKeberatan/ModalPermohonan.js

@@ -1,6 +1,6 @@
 import React, { Component } from "react";
 import Router from "next/router";
-import { Row, Col, FormGroup, Button, Modal, ModalHeader, ModalBody, ModalFooter } from "reactstrap";
+import { Row, Col, FormGroup, Button, Modal, ModalHeader, ModalBody, ModalFooter, Progress } from "reactstrap";
 import { addBanding } from "@/actions/banding";
 import { connect } from "react-redux";
 import { toast } from "react-toastify";
@@ -123,11 +123,18 @@ export class ModalPermohonan extends Component {
 	render() {
 		const { files } = this.state;
 
+		const removeFile = file => () => {
+			const newFiles = [...files]
+			newFiles.splice(newFiles.indexOf(file), 1)
+			this.setState({
+				files: newFiles,
+			});
+		}
 		const thumbs = files.map((file, index) => (
-			<div md={3} key={index}>
-				{/* <img className="img-fluid mb-2" src={file.preview} alt="Item" /> */}
-				<span className="text-center">{index + 1}.{file.name}</span>
-			</div>
+			<p>
+				<em className="far fa-file" />&nbsp;&nbsp;{file.name}
+				<button className="bg-transparent button-transparent border-0 fas fa-trash text-danger float-right" onClick={removeFile(file)} />
+			</p>
 		));
 		return (
 			<>
@@ -171,7 +178,10 @@ export class ModalPermohonan extends Component {
 																<input {...getInputProps()} />
 																<div className="dropzone-previews flex">
 																	<div className="dropzone-style-1">
-																		<div className="center-ver-hor dropzone-previews flex">{this.state.files.length > 0 ? <Row><span className="text-left">{thumbs}</span></Row> :
+																		<div className="center-ver-hor dropzone-previews flex">{this.state.files.length > 0 ?
+																			<div className="text-center fa-2x icon-cloud-upload mr-2 ">
+																				<h5 className="text-center dz-default dz-message">Klik untuk tambah file</h5>
+																			</div> :
 																			<div className="text-center fa-2x icon-cloud-upload mr-2 ">
 																				<h5 className="text-center dz-default dz-message">Klik untuk upload dokumen</h5>
 																			</div>
@@ -199,8 +209,11 @@ export class ModalPermohonan extends Component {
 												</DropzoneWrapper>
 											)}
 										</Field>
+										<div>
+											{thumbs}
+										</div>
 										<ErrorMessage name="dokumen" component="div" className="form-text text-danger" />
-										<p className="mrgn-top-5">
+										<p className="mrgn-top-5 font-color-black">
 											Ukuran setiap dokumen maksimal 15mb
 										</p>
 									</div>

+ 20 - 7
components/PT/Keberatan/ModalPermohonan.js

@@ -1,6 +1,6 @@
 import React, { Component } from "react";
 import Router from "next/router";
-import { Row, Col, FormGroup, Button, Modal, ModalHeader, ModalBody, ModalFooter } from "reactstrap";
+import { Row, Col, FormGroup, Button, Modal, ModalHeader, ModalBody, ModalFooter, Progress } from "reactstrap";
 import { addKeberatan } from "@/actions/keberatan";
 import { connect } from "react-redux";
 import { toast } from "react-toastify";
@@ -125,11 +125,18 @@ export class ModalPermohonan extends Component {
 	render() {
 		const { files } = this.state;
 
+		const removeFile = file => () => {
+			const newFiles = [...files]
+			newFiles.splice(newFiles.indexOf(file), 1)
+			this.setState({
+				files: newFiles,
+			});
+		}
 		const thumbs = files.map((file, index) => (
-			<div md={3} key={index}>
-				{/* <img className="img-fluid mb-2" src={file.preview} alt="Item" /> */}
-				<span className="text-center">{index + 1}.{file.name}</span>
-			</div>
+			<p>
+				<em className="far fa-file" />&nbsp;&nbsp;{file.name}
+				<button className="bg-transparent button-transparent border-0 fas fa-trash text-danger float-right" onClick={removeFile(file)} />
+			</p>
 		));
 		return (
 			<>
@@ -173,7 +180,10 @@ export class ModalPermohonan extends Component {
 																<input {...getInputProps()} />
 																<div className="dropzone-previews flex">
 																	<div className="dropzone-style-1">
-																		<div className="center-ver-hor dropzone-previews flex">{this.state.files.length > 0 ? <Row><span className="text-left">{thumbs}</span></Row> :
+																		<div className="center-ver-hor dropzone-previews flex">{this.state.files.length > 0 ?
+																			<div className="text-center fa-2x icon-cloud-upload mr-2 ">
+																				<h5 className="text-center dz-default dz-message">Klik untuk tambah file</h5>
+																			</div> :
 																			<div className="text-center fa-2x icon-cloud-upload mr-2 ">
 																				<h5 className="text-center dz-default dz-message">Klik untuk upload dokumen</h5>
 																			</div>
@@ -201,8 +211,11 @@ export class ModalPermohonan extends Component {
 												</DropzoneWrapper>
 											)}
 										</Field>
+										<div>
+											{thumbs}
+										</div>
 										<ErrorMessage name="dokumen" component="div" className="form-text text-danger" />
-										<p className="mrgn-top-5">
+										<p className="mrgn-top-5 font-color-black">
 											Ukuran setiap dokumen maksimal 15mb
 										</p>
 									</div>

+ 28 - 13
components/Pelaporan/InputData.js

@@ -3,7 +3,7 @@ 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, Button } from "reactstrap";
+import { Row, Col, FormGroup, Input, Button, Progress } from "reactstrap";
 import { connect } from "react-redux";
 import { ToastContainer, toast } from "react-toastify";
 import moment from "moment";
@@ -137,11 +137,14 @@ export class InputData extends Component {
 		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);
-			});
-		}
+		// if (data.dokumen.length > 0) {
+		// 	data.dokumen.forEach((e) => {
+		// 		formdata.append("dokumen", e);
+		// 	});
+		// }
+		this.state.files.forEach((e) => {
+			formdata.append("dokumen", e);
+		});
 
 		const create = createPelaporan(token, formdata);
 		await toast.promise(create, {
@@ -157,12 +160,18 @@ export class InputData extends Component {
 
 	render() {
 		const { selectedOptionMulti, files, pelanggaran } = this.state;
-
+		const removeFile = file => () => {
+			const newFiles = [...files]
+			newFiles.splice(newFiles.indexOf(file), 1)
+			this.setState({
+				files: newFiles,
+			});
+		}
 		const thumbs = files.map((file, index) => (
-			<div md={3} key={index}>
-				{/* <img className="img-fluid mb-2" src={file.preview} alt="Item" /> */}
-				<span className="text-left">{index + 1}.{file.name}</span>
-			</div>
+			<p>
+				<em className="far fa-file" />&nbsp;&nbsp;{file.name}
+				<button className="bg-transparent button-transparent border-0 fas fa-trash text-danger float-right" onClick={removeFile(file)} />
+			</p>
 		));
 		return (
 			<Formik
@@ -236,7 +245,10 @@ export class InputData extends Component {
 													<div {...getRootProps()} className={"dropzone card" + (isDragActive ? "dropzone-drag-active" : "")}>
 														<input name="dokumen" {...getInputProps()} />
 														<div className="dropzone-style-1">
-															<div className="center-ver-hor dropzone-previews flex">{this.state.files.length > 0 ? <Row><span className="text-left">{thumbs}</span></Row> :
+															<div className="center-ver-hor dropzone-previews flex">{this.state.files.length > 0 ?
+																<div className="text-center fa-2x icon-cloud-upload mr-2 ">
+																	<h5 className="text-center dz-default dz-message">Klik untuk tambah file</h5>
+																</div> :
 																<div className="text-center fa-2x icon-cloud-upload mr-2 ">
 																	<h5 className="text-center dz-default dz-message">Klik untuk upload dokumen</h5>
 																</div>
@@ -263,8 +275,11 @@ export class InputData extends Component {
 										</DropzoneWrapper>
 									)}
 								</Field>
+								<div>
+									{thumbs}
+								</div>
 								<ErrorMessage name="dokumen" component="div" className="form-text text-danger" />
-								<p className="mrgn-top-5">
+								<p className="mrgn-top-5 font-color-black">
 									Ukuran setiap dokumen maksimal 15mb
 								</p>
 							</div>

+ 19 - 8
components/Pemeriksaan/InputEvaluasi.js

@@ -3,7 +3,7 @@ import { insertPemeriksaan } from "@/actions/pemeriksaan";
 import Router from "next/router";
 import Datetime from "react-datetime";
 import moment from "moment";
-import { Row, Col, FormGroup, Input, Button } from "reactstrap";
+import { Row, Col, FormGroup, Input, Button, Progress } from "reactstrap";
 import { ToastContainer, toast } from "react-toastify";
 import { Formik, Form, Field, ErrorMessage } from "formik";
 import * as Yup from "yup";
@@ -126,7 +126,7 @@ class InputEvaluasi extends Component {
 		const formdata = new FormData();
 		formdata.append("judul", data.judul);
 		formdata.append("tanggal", data.tanggal);
-		data.dokumen.forEach((e) => {
+		this.state.files.forEach((e) => {
 			formdata.append("dokumen", e);
 		});
 		if (this.state.delegasichecklist == true) {
@@ -163,11 +163,18 @@ class InputEvaluasi extends Component {
 	render() {
 		const { files } = this.state;
 
+		const removeFile = file => () => {
+			const newFiles = [...files]
+			newFiles.splice(newFiles.indexOf(file), 1)
+			this.setState({
+				files: newFiles,
+			});
+		}
 		const thumbs = files.map((file, index) => (
-			<div md={3} key={index}>
-				{/* <img className="img-fluid mb-2" src={file.preview} alt="Item" /> */}
-				<span className="text-left">{index + 1}.{file.name}</span>
-			</div>
+			<p>
+				<em className="far fa-file" />&nbsp;&nbsp;{file.name}
+				<button className="bg-transparent button-transparent border-0 fas fa-trash text-danger float-right" onClick={removeFile(file)} />
+			</p>
 		));
 		return (
 			<>
@@ -224,7 +231,10 @@ class InputEvaluasi extends Component {
 													<div {...getRootProps()} className={"dropzone card" + (isDragActive ? "dropzone-drag-active" : "")}>
 														<input name="dokumen" {...getInputProps()} />
 														<div className="dropzone-style-1">
-															<div className="center-ver-hor dropzone-previews flex">{this.state.files.length > 0 ? <Row><span className="text-left">{thumbs}</span></Row> :
+															<div className="center-ver-hor dropzone-previews flex">{this.state.files.length > 0 ?
+																<div className="text-center fa-2x icon-cloud-upload mr-2 ">
+																	<h5 className="text-center dz-default dz-message">Klik untuk tambah file</h5>
+																</div> :
 																<div className="text-center fa-2x icon-cloud-upload mr-2 ">
 																	<h5 className="text-center dz-default dz-message">Klik untuk upload dokumen</h5>
 																</div>
@@ -251,8 +261,9 @@ class InputEvaluasi extends Component {
 										</DropzoneWrapper>
 									)}
 								</Field>
+								{thumbs}
 								<ErrorMessage name="dokumen" component="div" className="form-text text-danger" />
-								<p className="mrgn-top-5">
+								<p className="mrgn-top-5 font-color-black">
 									Ukuran setiap dokumen maksimal 15mb
 								</p>
 							</div>

+ 1 - 2
components/Penjadwalan/CaseProgress.js

@@ -106,8 +106,7 @@ function CaseProgress({ data, nextButton, prevButton, tahun, excelSemua, excelMe
 					<Button className="float-left button-hidden icon-next" onClick={nextButton}>
 						<img src="/static/img/next.png"></img>
 					</Button>
-					<b className="text-tahun">Tahun {tahun} </b>
-					<b className="text-tahun">Tahun {tahun} </b>
+					<b className="text-tahun">Tahun {tahun}</b>
 					<Dropdown className="float-right">
 						<Dropdown.Toggle variant="success" id="dropdown-basic">
 							Unduh

+ 19 - 6
components/PerpanjanganSanksi/InputTanggal.js

@@ -1,5 +1,5 @@
 import React, { Component } from "react";
-import { Row, Col, Card, CardBody, FormGroup, Input, Button, Modal, ModalHeader, ModalBody, ModalFooter, CardHeader, CardTitle } from "reactstrap";
+import { Row, Col, Card, CardBody, FormGroup, Input, Button, Progress } from "reactstrap";
 import { toast } from "react-toastify";
 import { Formik, Form, Field, ErrorMessage } from "formik";
 import * as Yup from "yup";
@@ -156,11 +156,18 @@ class InputTanggal extends Component {
     };
     render() {
         const { files, sanksi } = this.state;
-
+        const removeFile = file => () => {
+            const newFiles = [...files]
+            newFiles.splice(newFiles.indexOf(file), 1)
+            this.setState({
+                files: newFiles,
+            });
+        }
         const thumbs = files.map((file, index) => (
-            <div md={3} key={index}>
-                <span className="text-left">{index + 1}.{file.name}</span>
-            </div>
+            <p>
+                <em className="far fa-file" />&nbsp;&nbsp;{file.name}
+                <button className="bg-transparent button-transparent border-0 fas fa-trash text-danger float-right" onClick={removeFile(file)} />
+            </p>
         ));
         return (
             <Card className="card-default">
@@ -249,7 +256,10 @@ class InputTanggal extends Component {
                                                                 <input {...getInputProps()} />
                                                                 <div className="dropzone-previews flex">
                                                                     <div className="dropzone-style-1">
-                                                                        <div className="center-ver-hor dropzone-previews flex">{this.state.files.length > 0 ? <Row><span className="text-left">{thumbs}</span></Row> :
+                                                                        <div className="center-ver-hor dropzone-previews flex">{this.state.files.length > 0 ?
+                                                                            <div className="text-center fa-2x icon-cloud-upload mr-2 ">
+                                                                                <h5 className="text-center dz-default dz-message">Klik untuk tambah file</h5>
+                                                                            </div> :
                                                                             <div className="text-center fa-2x icon-cloud-upload mr-2 ">
                                                                                 <h5 className="text-center dz-default dz-message">Upload dokumen rekomendasi delegasi</h5>
                                                                             </div>
@@ -277,6 +287,9 @@ class InputTanggal extends Component {
                                                 </DropzoneWrapper>
                                             )}
                                         </Field>
+                                        <div>
+                                            {thumbs}
+                                        </div>
                                     </div>
                                 </FormGroup>
                                 <FormGroup row>

+ 6 - 8
components/PerpanjanganSanksi/TableLaporan.js

@@ -17,8 +17,6 @@ function TableLaporan({ listData, to, linkName, status = false, noBy = false })
 									<th>No.Laporan</th>
 									<th>Deskripsi Laporan</th>
 									{<th>TMT Berlaku</th>}
-									{/* {!noBy && <th>Dibuat Oleh</th>} */}
-									{/* <th>Created</th> */}
 									<th>Aksi</th>
 								</tr>
 							</thead>
@@ -31,7 +29,7 @@ function TableLaporan({ listData, to, linkName, status = false, noBy = false })
 												<div className="media align-items-center">
 													<div className="media-body d-flex">
 														<div>
-															<h4>{data.no_laporan}</h4>
+															<h4>{data.laporan.no_laporan}</h4>
 															<p>{moment(data.createdAt).format("DD-MMMM-YYYY")}</p>
 														</div>
 													</div>
@@ -43,8 +41,8 @@ function TableLaporan({ listData, to, linkName, status = false, noBy = false })
 													<div className="media align-items-center">
 														<div className="media-body d-flex">
 															<div>
-																<h4 className="m-0">{data.pt.nama.length > 64 ? data.pt.nama.substring(0, 64) + "..." : data.pt.nama}</h4>
-																<p className="w-105">{data.keterangan}</p>
+																<h4 className="m-0">{data.laporan.pt.nama.length > 64 ? data.laporan.pt.nama.substring(0, 64) + "..." : data.laporan.pt.nama}</h4>
+																<p className="w-105">{data.laporan.keterangan}</p>
 															</div>
 														</div>
 													</div>
@@ -53,8 +51,8 @@ function TableLaporan({ listData, to, linkName, status = false, noBy = false })
 
 
 											<td>
-												{data.sanksi.masa_berlaku?.to_date ? (<h4 className="m-0"> {moment(data.sanksi.masa_berlaku?.from_date).format("DD MMMM YYYY")} - {moment(data.sanksi.masa_berlaku?.to_date).format("DD MMMM YYYY")}</h4>) : (<h4 className="m-0">6 Bulan</h4>)}
-												<p className="w-105">{data.sanksi.keterangan}</p>
+												{data.masa_berlaku?.to_date ? (<h4 className="m-0"> {moment(data.masa_berlaku?.from_date).format("DD MMMM YYYY")} - {moment(data.masa_berlaku?.to_date).format("DD MMMM YYYY")}</h4>) : (<h4 className="m-0">6 Bulan</h4>)}
+												<p className="w-105">{data.keterangan}</p>
 											</td>
 											{!noBy && <td>{data.user.isPrivate ? "" : data.user.nama}</td>}
 											<td>
@@ -62,7 +60,7 @@ function TableLaporan({ listData, to, linkName, status = false, noBy = false })
 													<Link
 														href={{
 															pathname: to,
-															query: { id: data.sanksi?._id },
+															query: { id: data?._id },
 														}}
 													>
 														<Button className="btn-login" color>

+ 20 - 6
components/RekomendasiDelegasi/InputRekomendasi.js

@@ -1,6 +1,6 @@
 import React, { Component } from "react";
 import { insertPemeriksaan } from "@/actions/pemeriksaan";
-import { Row, Col, Card, CardBody, FormGroup, Input, Button, Modal, ModalHeader, ModalBody, ModalFooter, CardHeader, CardTitle } from "reactstrap";
+import { Row, Col, Card, CardBody, FormGroup, Input, Button, Progress } from "reactstrap";
 import { toast } from "react-toastify";
 import { Formik, Form, Field, ErrorMessage } from "formik";
 import * as Yup from "yup";
@@ -141,10 +141,18 @@ class InputRekomendasi extends Component {
 	render() {
 		const { files } = this.state;
 
+		const removeFile = file => () => {
+			const newFiles = [...files]
+			newFiles.splice(newFiles.indexOf(file), 1)
+			this.setState({
+				files: newFiles,
+			});
+		}
 		const thumbs = files.map((file, index) => (
-			<div md={3} key={index}>
-				<span className="text-left">{index + 1}.{file.name}</span>
-			</div>
+			<p>
+				<em className="far fa-file" />&nbsp;&nbsp;{file.name}
+				<button className="bg-transparent button-transparent border-0 fas fa-trash text-danger float-right" onClick={removeFile(file)} />
+			</p>
 		));
 		return (
 			<Card className="card-default">
@@ -179,7 +187,10 @@ class InputRekomendasi extends Component {
 																<input {...getInputProps()} />
 																<div className="dropzone-previews flex">
 																	<div className="dropzone-style-1">
-																		<div className="center-ver-hor dropzone-previews flex">{this.state.files.length > 0 ? <Row><span className="text-left">{thumbs}</span></Row> :
+																		<div className="center-ver-hor dropzone-previews flex">{this.state.files.length > 0 ?
+																			<div className="text-center fa-2x icon-cloud-upload mr-2 ">
+																				<h5 className="text-center dz-default dz-message">Klik untuk tambah file</h5>
+																			</div> :
 																			<div className="text-center fa-2x icon-cloud-upload mr-2 ">
 																				<h5 className="text-center dz-default dz-message">upload dokumen rekomendasi delegasi</h5>
 																			</div>
@@ -207,8 +218,11 @@ class InputRekomendasi extends Component {
 												</DropzoneWrapper>
 											)}
 										</Field>
+										<div>
+											{thumbs}
+										</div>
 										<ErrorMessage name="dokumen" component="div" className="form-text text-danger" />
-										<p className="mrgn-top-5">Ukuran setiap dokumen maksimal 15mb</p>
+										<p className="mrgn-top-5 font-color-black">Ukuran setiap dokumen maksimal 15mb</p>
 									</div>
 								</FormGroup>
 								<FormGroup row>

+ 46 - 0
components/Sanksi/BeritaAcara_A.js

@@ -0,0 +1,46 @@
+import React, { useRef, Component } from 'react';
+import { useReactToPrint } from "react-to-print";
+import { Row, Col, Button } from "reactstrap";
+import Head from 'next/head'
+import SignatureCanvas from 'react-signature-canvas'
+import ComponentToPrint from "./SuratBA";
+import ReactToPrint, { PrintContextConsumer } from 'react-to-print';
+import { getOneLaporan, updateLaporan } from "@/actions/pelaporan";
+
+
+class BeritaAcara extends Component {
+    constructor(props) {
+        super(props);
+        this.state = {
+        };
+    }
+    static getInitialProps = async ({ query }) => {
+        return { query };
+    };
+
+    render() {
+        return (
+            <div>
+                <ReactToPrint pageStyle='print' content={() => this.componentRef}>
+                    <PrintContextConsumer>
+                        {({ handlePrint }) => (
+                            <div className=' content-heading border-radius-login'>
+                                <span className="btn-radius">
+                                    <Button onClick={handlePrint} color className="btn-labeled-4">
+                                        <h4 className="p-0 mt-2">Print dan Download</h4>
+                                    </Button>
+                                </span>
+                            </div>
+
+                        )}
+                    </PrintContextConsumer>
+                </ReactToPrint>
+                {/* <div style={{ display: "none" }}> */}
+                <ComponentToPrint ref={el => (this.componentRef = el)} query={this.props.query} />
+                {/* </div> */}
+            </div >
+
+        );
+    }
+}
+export default BeritaAcara

+ 25 - 0
components/Sanksi/Ringkasan.js

@@ -193,6 +193,31 @@ function Ringkasan({ dataLaporan, dataPelanggaran, dataUpload }) {
 								</Scrollable>
 							</Col>
 						</FormGroup>
+						<FormGroup row>
+							<Col md="4">Surat Berita Acara:</Col>
+							<Col md="8">
+								<Scrollable height="120px" className="list-group">
+									<table className="table table-bordered bg-transparent">
+										<tbody>
+											{dataUpload
+												? dataUpload.filesBeritaAcara.map((e) => (
+													<tr>
+														<td>
+															<em className="fa-lg far fa-file-code"></em>
+														</td>
+														<td>
+															<a className="text-muted" href={e.preview} download={e.name}>
+																{e.name}
+															</a>
+														</td>
+													</tr>
+												))
+												: ""}
+										</tbody>
+									</table>
+								</Scrollable>
+							</Col>
+						</FormGroup>
 					</form>
 				</Col>
 			</Row>

+ 260 - 0
components/Sanksi/SuratBA.js

@@ -0,0 +1,260 @@
+import React, { Component } from 'react';
+import SignatureCanvas from 'react-signature-canvas'
+import { getOneLaporan, updateLaporan } from "@/actions/pelaporan";
+import { connect } from "react-redux";
+import moment from "moment";
+import 'moment/locale/id'
+moment.locale('id')
+
+
+
+class ComponentToPrint extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {
+            dataLaporan: {},
+        };
+    }
+
+    static getInitialProps = async ({ query }) => {
+        return { query };
+    };
+
+
+    componentDidMount = async () => {
+        const { query, token } = this.props;
+        const { id } = query;
+        const dataLaporan = await getOneLaporan(token, id);
+        this.setState({ dataLaporan });
+    };
+
+
+
+    render() {
+        const { dataLaporan, today } = this.state
+        return (
+            <div className='BA-div' >
+                <div className='BA-logo'>
+                    <img className='BA-logo' src="/static/img/logo-single-1-login.png" alt="logo" />
+                </div>
+                <div>
+                    <h3 className='BA-header'>LAPORAN HASIL EVALUASI DAN PEMBAHASAN</h3>
+                    {dataLaporan.data && (<h3 className='BA-header'>{dataLaporan.data.pt.nama}</h3>)}
+                    <div className='BA-body'>
+                        <p className='BA-body'>
+                            Pada hari ini <span>{moment(dataLaporan.createAt).locale("id").format("dddd")}</span>, tanggal&nbsp;{moment(dataLaporan.createAt).format("D")}&nbsp; bulan &nbsp;{moment(dataLaporan.createAt).format("MMMM")} tahun &nbsp;{moment(dataLaporan.createAt).format("YYYY")}, bertempat di<span contenteditable='true'>&nbsp;&nbsp;&nbsp;</span>, 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:
+                        </p>
+                        <div className='BA-body'>
+                            <ol>
+                                <li contenteditable='true'>Isi name</li>
+                                <li contenteditable='true'>Isi nama</li>
+                                <li contenteditable='true'>Isi nama</li>
+                            </ol>
+                        </div>
+                    </div>
+                </div>
+                <div className='BA-body'>
+                    <p className='BA-body'>
+                        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:
+                    </p>
+                    <div className='BA-body'>
+                        <ol>
+                            <li>Telah dibacakan Berita Acara Evaluasi Kinerja Perguruan Tinggi …….., tanggal ……..;</li>
+                            <li>Telah dilakukan pembahasan rekomendasi mengenai fakta-fakta yang ditemukan Tim EKPT Ditjen Diktiristek, dengan temuan sebagai berikut:</li>
+                            {/* <div style={{ overflow: "auto" }}> */}
+                            <table className='table-a'>
+                                <tbody>
+                                    <tr>
+                                        <th rowspan="2">NO</th>
+                                        <th rowspan="2">NAMA DAN IZIN PRODI</th>
+                                        <th colspan="3">PELANGGARAN TERHADAP PERMENDIKBUD NO.7 TAHUN 2020</th>
+                                        <th rowspan="2">SIMPULAN</th>
+                                        <th rowspan="2">REKOMENDASI</th>
+                                    </tr>
+                                    <tr>
+                                        <th>PASAL</th>
+                                        <th>BUTIR PELANGGARAN</th>
+                                        <th>DESKRIPSI PELANGGARAN</th>
+                                    </tr>
+                                    <tr>
+                                        <td>......</td>
+                                        <td>......</td>
+                                        <td>......</td>
+                                        <td>.....</td>
+                                        <td>......</td>
+                                        <td contenteditable='true'>Isi Table</td>
+                                        <td contenteditable='true'>Isi Table</td>
+                                    </tr>
+                                    <tr>
+                                        <td>&nbsp;</td>
+                                        <td>&nbsp;</td>
+                                        <td>&nbsp;</td>
+                                        <td>&nbsp;</td>
+                                        <td>&nbsp;</td>
+                                        <td contenteditable='true'>&nbsp;</td>
+                                        <td contenteditable='true'>&nbsp;</td>
+                                    </tr>
+                                    <tr>
+                                        <td>&nbsp;</td>
+                                        <td>&nbsp;</td>
+                                        <td>&nbsp;</td>
+                                        <td>&nbsp;</td>
+                                        <td>&nbsp;</td>
+                                        <td contenteditable='true'>&nbsp;</td>
+                                        <td contenteditable='true'>&nbsp;</td>
+                                    </tr>
+                                    <tr>
+                                        <td>&nbsp;</td>
+                                        <td>&nbsp;</td>
+                                        <td>&nbsp;</td>
+                                        <td>&nbsp;</td>
+                                        <td>&nbsp;</td>
+                                        <td contenteditable='true'>&nbsp;</td>
+                                        <td contenteditable='true'>&nbsp;</td>
+                                    </tr>
+                                    <tr>
+                                        <td>&nbsp;</td>
+                                        <td>&nbsp;</td>
+                                        <td>&nbsp;</td>
+                                        <td>&nbsp;</td>
+                                        <td>&nbsp;</td>
+                                        <td contenteditable='true'>&nbsp;</td>
+                                        <td contenteditable='true'>&nbsp;</td>
+                                    </tr>
+                                    <tr>
+                                        <td>&nbsp;</td>
+                                        <td>&nbsp;</td>
+                                        <td>&nbsp;</td>
+                                        <td>&nbsp;</td>
+                                        <td>&nbsp;</td>
+                                        <td contenteditable='true'>&nbsp;</td>
+                                        <td contenteditable='true'>&nbsp;</td>
+                                    </tr>
+                                    <tr>
+                                        <td>&nbsp;</td>
+                                        <td>&nbsp;</td>
+                                        <td>&nbsp;</td>
+                                        <td>&nbsp;</td>
+                                        <td>&nbsp;</td>
+                                        <td contenteditable='true'>&nbsp;</td>
+                                        <td contenteditable='true'>&nbsp;</td>
+                                    </tr>
+                                </tbody>
+                            </table>
+                            {/* </div> */}
+
+                            <li>Temuan Lain:
+                                <ol type="a">
+                                    <li contenteditable='true'>......</li>
+                                    <li contenteditable='true'>......</li>
+                                </ol>
+                            </li>
+                            <li>Hal-hal yang memberatkan, sebagai berikut:
+                                <ol type="a">
+                                    <li contenteditable='true'>......</li>
+                                    <li contenteditable='true'>......</li>
+                                </ol>
+                            </li>
+                            <li>hal-hal yang meringankan, sebagai berikut:
+                                <ol type="a">
+                                    <li contenteditable='true'>......</li>
+                                    <li contenteditable='true'>......</li>
+                                </ol>
+                            </li>
+                            <li>
+                                Berdasarkan pembahasan yang dilakukan, disepakati untuk merekomendasikan <strong contenteditable='true'>“Sanksi Administratif berupa …………………………..”.</strong>
+                            </li>
+                        </ol>
+                    </div>
+                    <p className='BA-body'>
+                        Demikian Laporan Evaluasi dan Pembahasan ini dibuat dengan sesungguhnya dan telah dibaca dan dicermati oleh peserta rapat yang hadir.
+                    </p>
+                    <table className='demo'>
+                        <tbody>
+                            <tr>
+                                <th colspan="4">PESERTA RAPAT PENYUSUNAN REKOMENDASI</th>
+                            </tr>
+                            <tr>
+                                <td contenteditable='true'>Isi Nama</td>
+                                <td>
+                                    <SignatureCanvas penColor='black' canvasProps={{ width: 200, height: 100, className: 'sigCanvas' }} />
+                                </td>
+                                <td contenteditable='true'>Isi Nama</td>
+                                <td>
+                                    <SignatureCanvas penColor='black' canvasProps={{ width: 200, height: 100, className: 'sigCanvas' }} />
+                                </td>
+                            </tr>
+                            <tr>
+                                <td contenteditable='true'>Isi Nama</td>
+                                <td>
+                                    <SignatureCanvas penColor='black' canvasProps={{ width: 200, height: 100, className: 'sigCanvas' }} />
+                                </td>
+                                <td contenteditable='true'>Isi Nama</td>
+                                <td>
+                                    <SignatureCanvas penColor='black' canvasProps={{ width: 200, height: 100, className: 'sigCanvas' }} />
+                                </td>
+                            </tr>
+                            <tr>
+                                <td contenteditable='true'>Isi Nama</td>
+                                <td>
+                                    <SignatureCanvas penColor='black' canvasProps={{ width: 200, height: 100, className: 'sigCanvas' }} />
+                                </td>
+                                <td contenteditable='true'>Isi Nama</td>
+                                <td>
+                                    <SignatureCanvas penColor='black' canvasProps={{ width: 200, height: 100, className: 'sigCanvas' }} />
+                                </td>
+                            </tr>
+                            <tr>
+                                <td contenteditable='true'>Isi Nama</td>
+                                <td>
+                                    <SignatureCanvas penColor='black' canvasProps={{ width: 200, height: 100, className: 'sigCanvas' }} />
+                                </td>
+                                <td contenteditable='true'>Isi Nama</td>
+                                <td>
+                                    <SignatureCanvas penColor='black' canvasProps={{ width: 200, height: 100, className: 'sigCanvas' }} />
+                                </td>
+                            </tr>
+                            <tr>
+                                <td contenteditable='true'>Isi Nama</td>
+                                <td>
+                                    <SignatureCanvas penColor='black' canvasProps={{ width: 200, height: 100, className: 'sigCanvas' }} />
+                                </td>
+                                <td contenteditable='true'>Isi Nama</td>
+                                <td>
+                                    <SignatureCanvas penColor='black' canvasProps={{ width: 200, height: 100, className: 'sigCanvas' }} />
+                                </td>
+                            </tr>
+                            <tr>
+                                <td contenteditable='true'>Isi Nama</td>
+                                <td>
+                                    <SignatureCanvas penColor='black' canvasProps={{ width: 200, height: 100, className: 'sigCanvas' }} />
+                                </td>
+                                <td contenteditable='true'>Isi Nama</td>
+                                <td>
+                                    <SignatureCanvas penColor='black' canvasProps={{ width: 200, height: 100, className: 'sigCanvas' }} />
+                                </td>
+                            </tr>
+                            <tr>
+                                <td contenteditable='true'>Isi Nama</td>
+                                <td>
+                                    <SignatureCanvas penColor='black' canvasProps={{ width: 200, height: 100, className: 'sigCanvas' }} />
+                                </td>
+                                <td contenteditable='true'>Isi Nama</td>
+                                <td>
+                                    <SignatureCanvas penColor='black' canvasProps={{ width: 200, height: 100, className: 'sigCanvas' }} />
+                                </td>
+                            </tr>
+                        </tbody>
+                    </table>
+                </div>
+                <div id="footer">
+                    <span>*LAPORAN HASIL EVALUASI DAN PEMBAHASAN …………. – …bulan&tahun…</span>
+                    {/* <span class="custom-footer-page-number">Number: </span> */}
+                </div>
+
+            </div>
+
+        );
+    }
+}
+export default ComponentToPrint

+ 40 - 2
components/Sanksi/TablePenetapanSanksi.js

@@ -2,6 +2,12 @@ import React, { Component } from "react";
 import { Card, Table } from "reactstrap";
 import { getPelanggaran } from "@/actions/pelanggaran";
 import { connect } from "react-redux";
+import Button from "reactstrap/lib/Button";
+import { getOneLaporan, updateLaporan } from "@/actions/pelaporan";
+import Router from "next/router";
+import { ToastContainer, toast } from "react-toastify";
+
+
 
 export class TablePenetapanSanksi extends Component {
 	checkedData = [];
@@ -11,6 +17,9 @@ export class TablePenetapanSanksi extends Component {
 		this.state = {
 			pelanggaran: null,
 			checkedData: [],
+			labelSanksi: [],
+			btnDelegasi: false,
+
 		};
 	}
 
@@ -28,8 +37,20 @@ export class TablePenetapanSanksi extends Component {
 		this.props.setCheckedData(this.checkedData);
 	};
 
+	setLabelSanksi = (evt, label_sanksi) => {
+		const checked = evt.target.checked;
+		const item = evt.target.value;
+		if (checked && label_sanksi === "Ringan") this.state.labelSanksi.push({ value: item, labelSanksi: label_sanksi });
+		else if (label_sanksi === "Ringan") this.state.labelSanksi = this.state.labelSanksi.filter((e) => e.value != item);
+	}
+
+	ondelegasi = () => {
+		this.props.handleDelegasi(this.state)
+	}
+
 	render() {
-		const { pelanggaran } = this.state;
+		const { pelanggaran, labelSanksi } = this.state;
+
 		return (
 			<Card className="card-default">
 				<Table bordered hover responsive>
@@ -72,7 +93,10 @@ export class TablePenetapanSanksi extends Component {
 									<td>
 										<div className="checkbox c-checkbox">
 											<label>
-												<input type="checkbox" value={jp._id} onChange={this.onHandleChange} />
+												<input type="checkbox" value={jp._id} onChange={(evt) => {
+													this.onHandleChange(evt)
+													this.setLabelSanksi(evt, jp.label_sanksi)
+												}} />
 												<span className="fa fa-check"></span>
 											</label>
 										</div>
@@ -82,6 +106,20 @@ export class TablePenetapanSanksi extends Component {
 							: ""}
 					</tbody>
 				</Table>
+				<div className="float-right m-2 ">
+					{
+						labelSanksi.length ? (
+							<Button className="btn-login float-right" color onClick={this.ondelegasi} >
+								<span className="font-color-white">
+									Delegasi ke LLDIKTI
+								</span>
+							</Button>
+						) : ("")
+
+
+					}
+				</div>
+
 			</Card>
 		);
 	}

+ 0 - 77
components/Sanksi/TmtDate.js

@@ -1,77 +0,0 @@
-import React from "react";
-import DatePicker from "react-datepicker";
-import "react-datepicker/dist/react-datepicker.css";
-import FormGroup from "reactstrap/lib/FormGroup";
-import ms from "ms";
-import { Component } from "react";
-import { addDays, addMonths } from 'date-fns';
-
-class TmtDate extends Component {
-	constructor(props) {
-		super(props);
-		const tmt_awal = new Date();
-		this.state = {
-			startDay: tmt_awal,
-			maxDay: "",
-			isiTmt: "",
-			awalsanksi: "",
-			akhirsanksi: "",
-		};
-	}
-	handleAwalSanksi = (awalsanksi) => {
-		this.setState({ awalsanksi });
-		// this.props.setUploadSuratSanksi(this.state);
-	};
-	handleAkhirSanksi = (akhirsanksi) => {
-		this.setState({ akhirsanksi });
-		// this.props.setUploadSuratSanksi(this.state);
-	};
-	render() {
-		return (
-			<div>
-				<FormGroup row className="mt-3">
-					<label className="col-md-2 col-form-label">Isi TMT</label>
-					<span className="col-sm-3 float-left">
-						<DatePicker
-							selected={this.state.awalsanksi}
-							onChange={(e) => {
-								this.handleAwalSanksi(e);
-								// this.props.setTmt({ startDate: this.state.awalsanksi, endDate: this.state.akhirsanksi });
-							}}
-							selectsStart
-							startDate={this.state.awalsanksi}
-							dateFormat="dd/MM/yyyy"
-							maxDate={this.state.startDay}
-							placeholderText="Dari Tanggal"
-							showDisabledMonthNavigation
-						/>
-					</span>
-					<span className="col-sm-3 float-right">
-						<DatePicker
-							selected={this.state.akhirsanksi}
-							onChange={(e) => {
-								this.handleAkhirSanksi(e);
-								// this.props.setTmt({ startDate: this.state.awalsanksi, endDate: this.state.akhirsanksi });
-							}}
-							selectsEnd
-							endDate={this.state.akhirsanksi}
-							dateFormat="dd/MM/yyyy"
-							minDate={this.state.awalsanksi}
-							maxDate={addMonths(new Date(this.state.awalsanksi), 6)}
-							placeholderText="Sampai tanggal"
-							showDisabledMonthNavigation
-						/>
-					</span>
-				</FormGroup>
-				<FormGroup row className="mt-1">
-					<label className="col-md-2 col-form-label">TMT berlaku</label>
-					<div className="col-md-10 mt-2">
-						<b>{this.state.awalsanksi ? moment(this.state.awalsanksi).format("DD-MM-YYYY") : "-"}</b> hingga <b>{this.state.akhirsanksi ? moment(this.state.akhirsanksi).format("DD-MM-YYYY") : "-"}</b>
-					</div>
-				</FormGroup>
-			</div>
-		);
-	}
-}
-
-export default TmtDate;

+ 105 - 15
components/Sanksi/UploadSurat.js

@@ -1,14 +1,14 @@
 import React, { Component } from "react";
-import { Row, Col, Input, FormGroup, Label } from "reactstrap";
+import { Row, Col, Input, FormGroup, Label, Progress } from "reactstrap";
 import Select from "react-select";
 import DatePicker from "react-datepicker";
 import "react-datepicker/dist/react-datepicker.css";
 // import "react-datepicker/dist/react-datepicker.css";
 import ms from "ms";
-import TmtDate from "./TmtDate";
 import { addDays, addMonths } from 'date-fns';
 import id from 'date-fns/locale/id';
 // registerLocale('id', id)
+import { getAutoSave, inputAutoSave } from "@/actions/autosave";
 
 let Dropzone = null;
 class DropzoneWrapper extends Component {
@@ -82,6 +82,8 @@ export class UploadSurat extends Component {
 			awalsanksi: "",
 			akhirsanksi: "",
 			tmtCheck: false,
+			filesBeritaAcara: [],
+			saveData: []
 		};
 	}
 
@@ -96,6 +98,33 @@ export class UploadSurat extends Component {
 		});
 		this.props.setUploadSuratSanksi(this.state);
 	};
+	onDropBA = (filesBeritaAcara) => {
+		this.setState({
+			filesBeritaAcara: filesBeritaAcara.map((file) =>
+				Object.assign(file, {
+					preview: URL.createObjectURL(file),
+				})
+			),
+			stat: "Added " + filesBeritaAcara.length + " file(s)",
+		});
+		this.props.setUploadSuratSanksi(this.state);
+	};
+
+	componentDidMount = async () => {
+		const { query, token } = this.props;
+		const { id } = query;
+		const getDataSave = await getAutoSave({ token, id, laporan: true });
+		const saveData = getDataSave.data?.penetapanSanksi;
+		this.setState(saveData)
+	}
+
+	handleAutoSave = async () => {
+		const { query, token } = this.props;
+		const { id } = query;
+		const { nomorSanksi, keterangan } = this.state
+		const saveData = await inputAutoSave({ data: { penetapanSanksi: { nomorSanksi, keterangan } }, token, id, laporan: true })
+
+	}
 
 	uploadFiles = (e) => {
 		e.preventDefault();
@@ -140,27 +169,45 @@ export class UploadSurat extends Component {
 		this.setState({ tmtCheck: !this.state.tmtCheck }, this.toRingkasan);
 	}
 	render() {
-		const { files } = this.state;
-
+		const { files, filesBeritaAcara } = this.state;
+		const removeFile = file => () => {
+			const newFiles = [...files]
+			newFiles.splice(newFiles.indexOf(file), 1)
+			this.setState({
+				files: newFiles,
+			});
+		}
+		const removeFileBA = file => () => {
+			const newFiles = [...filesBeritaAcara]
+			newFiles.splice(newFiles.indexOf(file), 1)
+			this.setState({
+				filesBeritaAcara: newFiles,
+			});
+		}
 		const thumbs = files.map((file, index) => (
-			<div md={3} key={index}>
-				<span className="text-left">
-					{index + 1}. {file.name}
-				</span>
-			</div>
+			<p>
+				<em className="far fa-file" />&nbsp;&nbsp;{file.name}
+				<button className="bg-transparent button-transparent border-0 fas fa-trash text-danger float-right" onClick={removeFile(file)} />
+			</p>
+		));
+		const thumbsBA = filesBeritaAcara.map((file, index) => (
+			<p>
+				<em className="far fa-file" />&nbsp;&nbsp;{file.name}
+				<button className="bg-transparent button-transparent border-0 fas fa-trash text-danger float-right" onClick={removeFileBA(file)} />
+			</p>
 		));
 		return (
 			<form className="form-horizontal" method="get" action="/" onSubmit={this.onSubmit}>
 				<FormGroup row>
 					<label className="col-md-2 col-form-label">Nomor Surat:</label>
 					<div className="col-md-10">
-						<Input type="text" value={this.state.nomorSanksi} onChange={this.setNomorSanksi} />
+						<Input type="text" value={this.state.nomorSanksi} onChange={(e) => { this.setNomorSanksi(e); this.handleAutoSave() }} />
 					</div>
 				</FormGroup>
 				<FormGroup row className="mt-3">
 					<label className="col-md-2 col-form-label">Keterangan</label>
 					<div className="col-md-10">
-						<Input type="textarea" value={this.state.keterangan} onChange={this.setKeterangan} required />
+						<Input type="textarea" value={this.state.keterangan} onChange={(e) => { this.setKeterangan(e); this.handleAutoSave() }} required />
 					</div>
 				</FormGroup>
 				<FormGroup row>
@@ -276,9 +323,9 @@ export class UploadSurat extends Component {
 										<div className="dropzone-style-1">
 											<div className="center-ver-hor dropzone-previews flex">
 												{this.state.files.length > 0 ? (
-													<Row>
-														<span className="text-left">{thumbs}</span>
-													</Row>
+													<div className="text-center fa-2x icon-cloud-upload mr-2 ">
+														<h5 className="text-center dz-default dz-message">Klik untuk tambah file</h5>
+													</div>
 												) : (
 													<div className="text-center fa-2x icon-cloud-upload mr-2 ">
 														<h5 className="text-center dz-default dz-message">Klik untuk upload dokumen</h5>
@@ -297,7 +344,50 @@ export class UploadSurat extends Component {
 								);
 							}}
 						</DropzoneWrapper>
-						<p className="mrgn-top-5">Ukuran setiap dokumen maksimal 15mb</p>
+						<div>
+							{thumbs}
+						</div>
+						<p className="mrgn-top-5 font-color-black">Ukuran setiap dokumen maksimal 15mb</p>
+					</div>
+				</FormGroup>
+				<FormGroup row>
+					<label className="col-md-2 col-form-label">
+						Berita Acara<span>: &nbsp;</span><span className="text-danger">*</span>
+					</label>
+					<div className="col-md-10">
+						<DropzoneWrapper className="" onDrop={this.onDropBA}>
+							{({ getRootProps, getInputProps, isDragActive }) => {
+								return (
+									<div {...getRootProps()} className={"dropzone card" + (isDragActive ? "dropzone-drag-active" : "")}>
+										<input {...getInputProps()} />
+										<div className="dropzone-style-1">
+											<div className="center-ver-hor dropzone-previews flex">
+												{this.state.filesBeritaAcara.length > 0 ? (
+													<div className="text-center fa-2x icon-cloud-upload mr-2 ">
+														<h5 className="text-center dz-default dz-message">Klik untuk tambah file</h5>
+													</div>
+												) : (
+													<div className="text-center fa-2x icon-cloud-upload mr-2 ">
+														<h5 className="text-center dz-default dz-message">Klik untuk upload dokumen</h5>
+													</div>
+												)}
+											</div>
+										</div>
+										<div className="d-flex align-items-center">
+											<small className="ml-auto">
+												<button type="button" className="btn btn-link" onClick={this.clearFiles}>
+													Reset dokumen
+												</button>
+											</small>
+										</div>
+									</div>
+								);
+							}}
+						</DropzoneWrapper>
+						<div>
+							{thumbsBA}
+						</div>
+						<p className="mrgn-top-5 font-color-black">Ukuran setiap dokumen maksimal 15mb</p>
 					</div>
 				</FormGroup>
 			</form >

+ 21 - 8
components/TurunSanksi/InputTanggal.js

@@ -1,5 +1,5 @@
 import React, { Component } from "react";
-import { Row, Col, Card, CardBody, FormGroup, Input, Button, Modal, ModalHeader, ModalBody, ModalFooter, CardHeader, CardTitle } from "reactstrap";
+import { Row, Col, Card, CardBody, FormGroup, Input, Button, Progress } from "reactstrap";
 import { toast } from "react-toastify";
 import { Formik, Form, Field, ErrorMessage } from "formik";
 import * as Yup from "yup";
@@ -173,11 +173,18 @@ class InputTanggal extends Component {
     };
     render() {
         const { files } = this.state;
-
+        const removeFile = file => () => {
+            const newFiles = [...files]
+            newFiles.splice(newFiles.indexOf(file), 1)
+            this.setState({
+                files: newFiles,
+            });
+        }
         const thumbs = files.map((file, index) => (
-            <div md={3} key={index}>
-                <span className="text-left">{index + 1}.{file.name}</span>
-            </div>
+            <p>
+                <em className="far fa-file" />&nbsp;&nbsp;{file.name}
+                <button className="bg-transparent button-transparent border-0 fas fa-trash text-danger float-right" onClick={removeFile(file)} />
+            </p>
         ));
         return (
             <Card className="card-default">
@@ -198,9 +205,9 @@ class InputTanggal extends Component {
                         {() => (
                             <Form className="form-horizontal">
                                 <FormGroup row>
-                                    <label className="col-md-2 col-form-label">Nomor Sanksi</label>
+                                    <label className="col-md-2 col-form-label">Nomor Surat</label>
                                     <div className="col-md-10">
-                                        <Field name="no_sanksi">{({ field }) => <Input type="textarea" placeholder="Nomor Sanksi" {...field} />}</Field>
+                                        <Field name="no_sanksi">{({ field }) => <Input type="textarea" placeholder="Nomor Surat" {...field} />}</Field>
                                         <ErrorMessage name="no_sanksi" component="div" className="form-text text-danger" />
                                     </div>
                                 </FormGroup>
@@ -345,7 +352,10 @@ class InputTanggal extends Component {
                                                                 <input {...getInputProps()} />
                                                                 <div className="dropzone-previews flex">
                                                                     <div className="dropzone-style-1">
-                                                                        <div className="center-ver-hor dropzone-previews flex">{this.state.files.length > 0 ? <Row><span className="text-left">{thumbs}</span></Row> :
+                                                                        <div className="center-ver-hor dropzone-previews flex">{this.state.files.length > 0 ?
+                                                                            <div className="text-center fa-2x icon-cloud-upload mr-2 ">
+                                                                                <h5 className="text-center dz-default dz-message">Klik untuk tambah file</h5>
+                                                                            </div> :
                                                                             <div className="text-center fa-2x icon-cloud-upload mr-2 ">
                                                                                 <h5 className="text-center dz-default dz-message">Upload dokumen rekomendasi delegasi</h5>
                                                                             </div>
@@ -373,6 +383,9 @@ class InputTanggal extends Component {
                                                 </DropzoneWrapper>
                                             )}
                                         </Field>
+                                        <div>
+                                            {thumbs}
+                                        </div>
                                     </div>
                                 </FormGroup>
                                 <FormGroup row>

+ 39 - 0
package-lock.json

@@ -9210,6 +9210,15 @@
         }
       }
     },
+    "react-signature-canvas": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/react-signature-canvas/-/react-signature-canvas-1.0.6.tgz",
+      "integrity": "sha512-NoMHomYu9HxFeLjUGbIeV9abPdWSROfFxFNDekGdwmmaIx+w5ziOEiU2C34X0Ao4GxFnwqyUy/BpYlA4lCD1CA==",
+      "requires": {
+        "signature_pad": "^2.3.2",
+        "trim-canvas": "^0.1.0"
+      }
+    },
     "react-sticky": {
       "version": "6.0.3",
       "resolved": "https://registry.npmjs.org/react-sticky/-/react-sticky-6.0.3.tgz",
@@ -9219,6 +9228,26 @@
         "raf": "^3.3.0"
       }
     },
+    "react-to-print": {
+      "version": "2.14.11",
+      "resolved": "https://registry.npmjs.org/react-to-print/-/react-to-print-2.14.11.tgz",
+      "integrity": "sha512-sePHBaCtZLp8/g4d/gRyI9XQZkveZq6xoukanAHfkzlXOa7sTuXCEQOYq37lIa5MkUoxySdJxYuyClaXPa9Zpg==",
+      "requires": {
+        "prop-types": "^15.8.1"
+      },
+      "dependencies": {
+        "prop-types": {
+          "version": "15.8.1",
+          "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+          "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
+          "requires": {
+            "loose-envify": "^1.4.0",
+            "object-assign": "^4.1.1",
+            "react-is": "^16.13.1"
+          }
+        }
+      }
+    },
     "react-toastify": {
       "version": "8.2.0",
       "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-8.2.0.tgz",
@@ -10055,6 +10084,11 @@
       "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
       "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
     },
+    "signature_pad": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/signature_pad/-/signature_pad-2.3.2.tgz",
+      "integrity": "sha512-peYXLxOsIY6MES2TrRLDiNg2T++8gGbpP2yaC+6Ohtxr+a2dzoaqWosWDY9sWqTAAk6E/TyQO+LJw9zQwyu5kA=="
+    },
     "simple-concat": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
@@ -10991,6 +11025,11 @@
       "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz",
       "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc="
     },
+    "trim-canvas": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/trim-canvas/-/trim-canvas-0.1.2.tgz",
+      "integrity": "sha512-nd4Ga3iLFV94mdhW9JFMLpQbHUyCQuhFOD71PEAt1NjtMD5wbZctzhX8c3agHNybMR5zXD1XTGoIEWk995E6pQ=="
+    },
     "trim-newlines": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",

+ 2 - 0
package.json

@@ -99,7 +99,9 @@
     "react-perfect-scrollbar": "1.5.8",
     "react-redux": "^7.2.6",
     "react-select": "^3.0.4",
+    "react-signature-canvas": "^1.0.6",
     "react-sticky": "^6.0.3",
+    "react-to-print": "^2.14.11",
     "react-toastify": "8.2.0",
     "react-transition-group": "4.2.2",
     "reactstrap": "^8.0.1",

+ 1 - 1
pages/app/index.js

@@ -112,7 +112,7 @@ class App extends Component {
               </Col>
             </Row>
           </Jumbotron>
-          <span>Version 2.1 ~ 1.88</span>
+          <span>Version 2.2 ~ 1.96</span>
         </ContentWrapper>
       </div>
     );

+ 38 - 1
pages/app/laporan-delegasi/index.js

@@ -9,6 +9,8 @@ import { connect } from "react-redux";
 import Loader from "@/components/Common/Loader";
 import Router from "next/router";
 import { createLog } from "@/actions/log";
+import swal from "sweetalert2";
+
 
 class Pelaporan extends Component {
 	constructor(props) {
@@ -49,6 +51,41 @@ class Pelaporan extends Component {
 		Router.push(url);
 	};
 
+	excelMenu = () => {
+		const url = getExcel(this.props.token, "Laporan", {
+			tahun: this.state.tahun,
+			pelaporan: true,
+		});
+		if (this.state.graph.data.jumlah_laporan.dikti && this.state.graph.data.jumlah_laporan.ditutup && this.state.graph.data.jumlah_laporan.lldikti) {
+			Router.push(url);
+		} else {
+			swal.fire({
+				title: "Data Kosong",
+				icon: "error",
+				confirmButtonColor: "#3e3a8e",
+			});
+		}
+	};
+	excelSemua = () => {
+		const url = getExcel(this.props.token, "Laporan", {
+			tahun: this.state.tahun,
+			pelaporan: true,
+			penjadwalan: true,
+			pemeriksaan: true,
+			sanksi: true,
+
+		});
+		if (this.state.graph.data.jumlah_laporan.dikti && this.state.graph.data.jumlah_laporan.ditutup && this.state.graph.data.jumlah_laporan.lldikti) {
+			Router.push(url);
+		} else {
+			swal.fire({
+				title: "Data Kosong",
+				icon: "error",
+				confirmButtonColor: "#3e3a8e",
+			});
+		}
+	};
+
 	render() {
 		const { pelaporan, graph } = this.state;
 		return (
@@ -57,7 +94,7 @@ class Pelaporan extends Component {
 					<div className="font-color-white">Laporan Delegasi</div>
 				</div>
 				<Row>
-					<Col lg="4">{graph?.data ? <CaseProgress data={graph.data} nextButton={this.nextButton} prevButton={this.prevButton} tahun={this.state.tahun} excel={this.excel} /> : <Loader />}</Col>
+					<Col lg="4">{graph?.data ? <CaseProgress data={graph.data} nextButton={this.nextButton} prevButton={this.prevButton} tahun={this.state.tahun} excel={this.excel} excelMenu={this.excelMenu} excelSemua={this.excelSemua} /> : <Loader />}</Col>
 					<Col lg="8">{pelaporan?.data ? <TableLaporan listData={pelaporan.data} to="/app/laporan-delegasi/detail" linkName="Detail" /> : <Loader />}</Col>
 				</Row>
 			</ContentWrapper>

+ 19 - 11
pages/app/pelaporan/index.js

@@ -10,6 +10,7 @@ import { connect } from "react-redux";
 import Loader from "@/components/Common/Loader";
 import Router from "next/router";
 import { createLog } from "@/actions/log";
+import swal from "sweetalert2";
 
 class Pelaporan extends Component {
 	constructor(props) {
@@ -65,7 +66,15 @@ class Pelaporan extends Component {
 			tahun: this.state.tahun,
 			pelaporan: true,
 		});
-		Router.push(url);
+		if (this.state.graph.data.jumlah_laporan.dikti && this.state.graph.data.jumlah_laporan.ditutup && this.state.graph.data.jumlah_laporan.lldikti) {
+			Router.push(url);
+		} else {
+			swal.fire({
+				title: "Data Kosong",
+				icon: "error",
+				confirmButtonColor: "#3e3a8e",
+			});
+		}
 	};
 	excelSemua = () => {
 		const url = getExcel(this.props.token, "Laporan", {
@@ -76,17 +85,16 @@ class Pelaporan extends Component {
 			sanksi: true,
 
 		});
-		Router.push(url);
+		if (this.state.graph.data.jumlah_laporan.dikti && this.state.graph.data.jumlah_laporan.ditutup && this.state.graph.data.jumlah_laporan.lldikti) {
+			Router.push(url);
+		} else {
+			swal.fire({
+				title: "Data Kosong",
+				icon: "error",
+				confirmButtonColor: "#3e3a8e",
+			});
+		}
 	};
-
-	// excel = () => {
-	// 	const url = getExcel(this.props.token, "Laporan", {
-	// 		tahun: this.state.tahun,
-	// 		pelaporan: true,
-	// 	});
-	// 	Router.push(url);
-	// };
-
 	render() {
 		const { pelaporan, graph, newLaporan } = this.state;
 

+ 3 - 2
pages/app/pemantauan/timeline.js

@@ -32,15 +32,16 @@ class Pemantauan extends Component {
 	componentDidMount = async () => {
 		const { query, token } = this.props;
 		const ptId = query.ptId;
-		const pelaporan = await getPelaporan(token, { pt_id: ptId, all: true, aktif: false });
+		const pelaporan = await getPelaporan(token, { pt_id: ptId, all: true, aktif: true });
 		const pt = await getOnePT(token, ptId);
 		this.setState({ pelaporan, pt });
+
 	};
 
 	handleLihatPemantaun = async (e, id_laporan) => {
 		const { token } = this.props;
 		const log = await getLog(token, id_laporan);
-		const detailLaporanPt = await getOneLaporan(token, id_laporan, { all: true, aktif: false });
+		const detailLaporanPt = await getOneLaporan(token, id_laporan, { all: true, aktif: true });
 		this.setState({ detailLaporanPt, log });
 	};
 

+ 24 - 2
pages/app/pemeriksaan/index.js

@@ -10,6 +10,8 @@ import Loader from "@/components/Common/Loader";
 import Link from "next/link";
 import Button from "reactstrap/lib/Button";
 import Router from "next/router";
+import swal from "sweetalert2";
+
 
 class Pemeriksaan extends Component {
 	constructor(props) {
@@ -43,13 +45,24 @@ class Pemeriksaan extends Component {
 	shouldComponentUpdate = (prevProps, prevState) => {
 		if (prevState.graph !== this.state.graph) return true;
 	};
+
+
 	excelMenu = () => {
 		const url = getExcel(this.props.token, "Laporan", {
 			tahun: this.state.tahun,
 			pemeriksaan: true,
 		});
-		Router.push(url);
+		if (this.state.graph.data.evaluasi.hasEvaluasi) {
+			Router.push(url);
+		} else {
+			swal.fire({
+				title: "Data Kosong",
+				icon: "error",
+				confirmButtonColor: "#3e3a8e",
+			});
+		}
 	};
+
 	excelSemua = () => {
 		const url = getExcel(this.props.token, "Laporan", {
 			tahun: this.state.tahun,
@@ -59,11 +72,20 @@ class Pemeriksaan extends Component {
 			sanksi: true,
 
 		});
-		Router.push(url);
+		if (this.state.graph.data.evaluasi.hasEvaluasi) {
+			Router.push(url);
+		} else {
+			swal.fire({
+				title: "Data Kosong",
+				icon: "error",
+				confirmButtonColor: "#3e3a8e",
+			});
+		}
 	};
 	excel = () => {
 		const url = getExcel(this.props.token, "Laporan", { tahun: this.state.tahun });
 		Router.push(url);
+
 	};
 
 	render() {

+ 20 - 2
pages/app/penjadwalan/index.js

@@ -10,6 +10,8 @@ import Loader from "@/components/Common/Loader";
 import Link from "next/link";
 import Button from "reactstrap/lib/Button";
 import Router from "next/router";
+import swal from "sweetalert2";
+
 
 class Penjadwalan extends Component {
 	constructor(props) {
@@ -48,7 +50,15 @@ class Penjadwalan extends Component {
 			tahun: this.state.tahun,
 			penjadwalan: true,
 		});
-		Router.push(url);
+		if (this.state.graph.data.jadwal.hasJadwal && this.state.graph.data.jadwal.notHasJadwal) {
+			Router.push(url);
+		} else {
+			swal.fire({
+				title: "Data Kosong",
+				icon: "error",
+				confirmButtonColor: "#3e3a8e",
+			});
+		}
 	};
 	excelSemua = () => {
 		const url = getExcel(this.props.token, "Laporan", {
@@ -59,7 +69,15 @@ class Penjadwalan extends Component {
 			sanksi: true,
 
 		});
-		Router.push(url);
+		if (this.state.graph.data.jadwal.hasJadwal && this.state.graph.data.jadwal.notHasJadwal) {
+			Router.push(url);
+		} else {
+			swal.fire({
+				title: "Data Kosong",
+				icon: "error",
+				confirmButtonColor: "#3e3a8e",
+			});
+		}
 	};
 
 	excel = () => {

+ 1 - 1
pages/app/perpanjangan-sanksi/index.js

@@ -34,7 +34,7 @@ class PerpanjanganSanksi extends Component {
 				</div>
 				<Row>
 					{/* <Col lg="12">{graph?.data ? <CaseProgress data={graph.data} nextButton={this.nextButton} prevButton={this.prevButton} tahun={this.state.tahun} excel={this.excel} /> : <Loader />}</Col> */}
-					<Col lg="12">{sanksi?.data ? <TableLaporan status noBy listData={pelaporan.data} to="/app/perpanjangan-sanksi/detail" linkName="Detail" /> : <Loader />}</Col>
+					<Col lg="12">{sanksi?.data ? <TableLaporan status noBy listData={sanksi.data} to="/app/perpanjangan-sanksi/detail" linkName="Detail" /> : <Loader />}</Col>
 				</Row>
 			</ContentWrapper>
 		);

+ 20 - 2
pages/app/sanksi/index.js

@@ -10,6 +10,8 @@ import Loader from "@/components/Common/Loader";
 import Link from "next/link";
 import Button from "reactstrap/lib/Button";
 import Router from "next/router";
+import swal from "sweetalert2";
+
 
 class Sanksi extends Component {
 	constructor(props) {
@@ -48,7 +50,15 @@ class Sanksi extends Component {
 			tahun: this.state.tahun,
 			sanksi: true,
 		});
-		Router.push(url);
+		if (this.state.graph.data.sanksi.hasSanksi && this.state.graph.data.sanksi.notHasSanksi) {
+			Router.push(url);
+		} else {
+			swal.fire({
+				title: "Data Kosong",
+				icon: "error",
+				confirmButtonColor: "#3e3a8e",
+			});
+		}
 	};
 	excelSemua = () => {
 		const url = getExcel(this.props.token, "Laporan", {
@@ -59,7 +69,15 @@ class Sanksi extends Component {
 			sanksi: true,
 
 		});
-		Router.push(url);
+		if (this.state.graph.data.sanksi.hasSanksi && this.state.graph.data.sanksi.notHasSanksi) {
+			Router.push(url);
+		} else {
+			swal.fire({
+				title: "Data Kosong",
+				icon: "error",
+				confirmButtonColor: "#3e3a8e",
+			});
+		}
 	};
 
 	excel = () => {

+ 63 - 12
pages/app/sanksi/proses.js

@@ -10,12 +10,15 @@ import UploadSurat from "@/components/Sanksi/UploadSurat";
 import Ringkasan from "@/components/Sanksi/Ringkasan";
 import TablePenetapanSanksi from "@/components/Sanksi/TablePenetapanSanksi";
 import Link from "next/link";
-import { getOneLaporan } from "@/actions/pelaporan";
+import { getOneLaporan, updateLaporan } from "@/actions/pelaporan";
 import { createSanksi } from "@/actions/sanksi";
 import { getPelanggaran, getPelanggaranSanksi } from "@/actions/pelanggaran";
 import { connect } from "react-redux";
 import Loader from "@/components/Common/Loader";
 import { ToastContainer, toast } from "react-toastify";
+import BeritaAcara from "@/components/Sanksi/BeritaAcara_A";
+import { autosave } from "@/actions/autosave";
+
 
 const stepNavitemStyle = {
 	backgroundColor: "#fcfcfc",
@@ -30,7 +33,8 @@ class ProsesSanksi extends Component {
 			dataUpload: null,
 			dataPelanggaran: {},
 			pelaporan: {},
-			listSanksi: []
+			listSanksi: [],
+			dataSave: {}
 		};
 	}
 
@@ -42,7 +46,7 @@ class ProsesSanksi extends Component {
 		const { query, token } = this.props;
 		const { id } = query;
 		const pelaporan = await getOneLaporan(token, id);
-		const {data:listSanksi} = await getPelanggaranSanksi(token)
+		const { data: listSanksi } = await getPelanggaranSanksi(token)
 		this.setState({ pelaporan, listSanksi });
 	};
 
@@ -63,6 +67,11 @@ class ProsesSanksi extends Component {
 					formdata.append("dokumen", e);
 				});
 			}
+			if (this.state.dataUpload.filesBeritaAcara.length > 0) {
+				this.state.dataUpload.filesBeritaAcara.forEach((e) => {
+					formdata.append("berita_acara", e);
+				});
+			}
 			await createSanksi(token, id, formdata);
 			toast.update(toastid, { render: "All is good", type: "success", isLoading: false, autoClose: true, closeButton: true });
 			Router.push({
@@ -73,6 +82,24 @@ class ProsesSanksi extends Component {
 		}
 	};
 
+
+	handleDelegasi = async (data) => {
+		const { token, query } = this.props;
+		const { id } = query;
+		let update = null;
+		const toastid = toast.loading("Please wait...");
+		data.change_role = "true";
+		data.keterangan = "delegasi ke DIKTI"
+		update = await updateLaporan(token, id, data);
+
+		if (!update) {
+			toast.update(toastid, { render: "Laporan gagal didelegasi", type: "error", isLoading: false, autoClose: true, closeButton: true });
+		} else {
+			toast.update(toastid, { render: "Laporan berhasil didelegasi", type: "success", isLoading: false, autoClose: true, closeButton: true });
+			Router.push("/app/sanksi");
+		}
+	};
+
 	toggleStep = (activeStep) => () => {
 		if (this.state.activeStep !== activeStep) {
 			this.setState({
@@ -111,7 +138,7 @@ class ProsesSanksi extends Component {
 						<CardBody>
 							<Row>
 								<Col xs="4">
-									<Nav pills vertical={true}>
+									<Nav pills vertical={true} className="cursor-pointer">
 										<NavItem style={stepNavitemStyle}>
 											<NavLink
 												tag="div"
@@ -153,7 +180,7 @@ class ProsesSanksi extends Component {
 												})}
 												onClick={this.toggleStep("4")}
 											>
-												<h4 className="text-left my-3">4. Penetapan Sanksi</h4>
+												<h4 className="text-left my-3">4. Berita Acara Pleno</h4>
 											</NavLink>
 										</NavItem>
 										<NavItem style={stepNavitemStyle}>
@@ -164,7 +191,18 @@ class ProsesSanksi extends Component {
 												})}
 												onClick={this.toggleStep("5")}
 											>
-												<h4 className="text-left my-3">5. Ringkasan</h4>
+												<h4 className="text-left my-3">5. Penetapan Sanksi</h4>
+											</NavLink>
+										</NavItem>
+										<NavItem style={stepNavitemStyle}>
+											<NavLink
+												tag="div"
+												className={classnames({
+													active: this.state.activeStep === "6",
+												})}
+												onClick={this.toggleStep("6")}
+											>
+												<h4 className="text-left my-3">6. Ringkasan</h4>
 											</NavLink>
 										</NavItem>
 									</Nav>
@@ -209,7 +247,7 @@ class ProsesSanksi extends Component {
 										<TabPane tabId="3">
 											<div className="pt-3 mb-3">
 												<h2>Penetapan Jenis Pelanggaran</h2>
-												<TablePenetapanSanksi setCheckedData={this.setCheckedData} />
+												<TablePenetapanSanksi handleDelegasi={this.handleDelegasi} setCheckedData={this.setCheckedData} dataPelanggaran={dataPelanggaran.data} data={pelaporan.data} />
 											</div>
 											<hr />
 											<div className="d-flex">
@@ -222,28 +260,41 @@ class ProsesSanksi extends Component {
 											</div>
 										</TabPane>
 										<TabPane tabId="4">
+											<Card>
+												<BeritaAcara query={this.props.query} />
+											</Card>
+											<div className="d-flex">
+												<Button color className="btn-login color-3e3a8e" onClick={this.toggleStep("3")}>
+													<span className="font-color-white">Previous</span>
+												</Button>
+												<Button className="ml-auto btn-login color-3e3a8e" color onClick={this.toggleStep("5")}>
+													<span className="font-color-white">Next</span>
+												</Button>
+											</div>
+										</TabPane>
+										<TabPane tabId="5">
 											<div className="pt-3 mb-3">
 												<h2>Penetapan Sanksi</h2>
-												{this.state.listSanksi && <UploadSurat setUploadSuratSanksi={this.setUploadSuratSanksi} listSanksi={this.state.listSanksi} />}
+												{this.state.listSanksi && <UploadSurat setUploadSuratSanksi={this.setUploadSuratSanksi} listSanksi={this.state.listSanksi} dataPelanggaran={dataPelanggaran.data} query={this.props.query} />}
 											</div>
 											<hr />
 											<div className="d-flex">
-												<Button color className="btn-login color-3e3a8e" onClick={this.toggleStep("3")}>
+												<Button color className="btn-login color-3e3a8e" onClick={this.toggleStep("4")}>
 													<span className="font-color-white">Previous</span>
 												</Button>
-												<Button className="ml-auto btn-login color-3e3a8e" color onClick={this.toggleStep("5")}>
+												<Button className="ml-auto btn-login color-3e3a8e" color onClick={this.toggleStep("6")}>
 													<span className="font-color-white">Next</span>
 												</Button>
 											</div>
 										</TabPane>
-										<TabPane tabId="5">
+										<TabPane tabId="6">
 											<div className="pt-3 mb-3">
 												<h2>Ringkasan</h2>
 												{pelaporan.data ? <Ringkasan dataLaporan={pelaporan.data} dataPelanggaran={dataPelanggaran.data} dataUpload={dataUpload} /> : <Loader />}
 											</div>
 											<hr />
 											<div className="d-flex">
-												<Button color className="btn-login color-3e3a8e" onClick={this.toggleStep("4")}>
+												<Button color className="btn-login color-3e3a8e" onClick={this.toggleStep("5")}>
 													<span className="font-color-white">Previous</span>
 												</Button>
 												<Button className="ml-auto btn-login color-3e3a8e" color onClick={this.done}>

+ 36 - 6
pages/app/tuntas/index.js

@@ -10,6 +10,8 @@ import Loader from "@/components/Common/Loader";
 import Link from "next/link";
 import Button from "reactstrap/lib/Button";
 import Router from "next/router";
+import swal from "sweetalert2";
+
 
 class PelaporanTuntas extends Component {
     constructor(props) {
@@ -37,14 +39,26 @@ class PelaporanTuntas extends Component {
 
     nextButton = async () => {
         const tahun = this.state.tahun + 1;
-        const graph = await getGraph(this.props.token, { evaluasi: true, listJadwal: true, tahun });
-        this.setState({ graph, tahun });
+        const { token } = this.props;
+        let laporanSelesai = await getlaporanselesai(token);
+        laporanSelesai = {
+            ...laporanSelesai, data: {
+                ...laporanSelesai.data, laporan: [...laporanSelesai.data.laporan, ...laporanSelesai.data.sanksi], sanksi: null
+            }
+        }
+        this.setState({ laporanSelesai, tahun });
     };
 
     prevButton = async () => {
         const tahun = this.state.tahun - 1;
-        const graph = await getGraph(this.props.token, { evaluasi: true, listJadwal: true, tahun });
-        this.setState({ graph, tahun });
+        const { token } = this.props;
+        let laporanSelesai = await getlaporanselesai(token);
+        laporanSelesai = {
+            ...laporanSelesai, data: {
+                ...laporanSelesai.data, laporan: [...laporanSelesai.data.laporan, ...laporanSelesai.data.sanksi], sanksi: null
+            }
+        }
+        this.setState({ laporanSelesai, tahun });
     };
 
     shouldComponentUpdate = (prevProps, prevState) => {
@@ -60,7 +74,15 @@ class PelaporanTuntas extends Component {
             tahun: this.state.tahun,
             pelaporan: true,
         });
-        Router.push(url);
+        if (this.state.graph.data.jumlah_ditutup && this.state.graph.data.jumlah_selesai) {
+            Router.push(url);
+        } else {
+            swal.fire({
+                title: "Data Kosong",
+                icon: "error",
+                confirmButtonColor: "#3e3a8e",
+            });
+        }
     };
     excelSemua = () => {
         const url = getExcel(this.props.token, "Laporan", {
@@ -71,7 +93,15 @@ class PelaporanTuntas extends Component {
             sanksi: true,
 
         });
-        Router.push(url);
+        if (this.state.graph.data.jumlah_ditutup && this.state.graph.data.jumlah_selesai) {
+            Router.push(url);
+        } else {
+            swal.fire({
+                title: "Data Kosong",
+                icon: "error",
+                confirmButtonColor: "#3e3a8e",
+            });
+        }
     };
 
     render() {

+ 94 - 25
styles/app/common/bootstrap-reset.scss

@@ -13,7 +13,9 @@
 
 a {
     outline: none !important;
+
     &.text-muted {
+
         &:hover,
         &:focus {
             color: darken($text-muted, 10%);
@@ -34,9 +36,11 @@ hr {
     padding: 0.1875rem 0.4375rem;
     font-size: 0.75rem;
     border-radius: 0.625rem;
+
     &.badge-warning {
         color: #fff !important;
     }
+
     &.badge-secondary {
         background-color: $gray-dark;
         color: #fff;
@@ -45,16 +49,20 @@ hr {
 
 .list-group {
     line-height: 1.3;
+
     .list-group-item {
         padding: 10px;
         color: #555;
+
         &.active {
             color: #fff;
+
             .badge {
                 background-color: #fff;
                 color: $primary;
             }
         }
+
         .card>& {
             border: 0;
         }
@@ -74,22 +82,27 @@ hr {
 .card {
     border-color: transparent;
     box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
+
     .card-header {
         border-bottom: 0;
         padding: 0.625rem 0.9375rem;
         background-color: transparent;
+
         .card-title {
             margin-bottom: 0;
             font-size: 1rem;
         }
+
         a {
             text-decoration: none !important;
         }
     }
 }
+
 .card-body {
     padding: 20px; //15px
 }
+
 .card-footer {
     padding: 0.625rem 0.9375rem;
 }
@@ -111,9 +124,12 @@ hr {
 .jumbotron {
     border: 1px solid $gray;
     background-color: #fff;
+
     @include media-breakpoint-up(md) {
-        padding: $jumbotron-padding ($jumbotron-padding/2);
-    }
+        padding: $jumbotron-padding (
+            $jumbotron-padding/2
+        );
+}
 }
 
 .nav-tabs>.nav-item>.nav-link {
@@ -124,8 +140,10 @@ hr {
     border: 1px solid $gray;
     border-radius: 0;
     padding: 10px 20px;
+
     &.active {
         background-color: $nav-tabs-link-active-bg;
+
         &,
         &:hover,
         &:focus {
@@ -140,10 +158,12 @@ hr {
     border-style: solid;
     border-width: 0 1px 1px 1px;
     border-color: $gray;
+
     .nav-pills+& {
         border: 0;
         padding: 0;
     }
+
     .p-0 & {
         padding: 0 !important
     }
@@ -156,14 +176,17 @@ hr {
     -webkit-appearance: none;
     outline: none !important; // padding: 0.375rem 1rem;
     @include transition(all .1s);
+
     &.btn-link {
         box-shadow: none;
         border: 0;
     }
+
     .input-group & {
         font-size: 14px;
         border-color: $input-border-color;
     }
+
     .input-group .form-control-sm+.input-group-btn & {
         font-size: 0.8125rem;
         padding: 0.3125rem 0.625rem;
@@ -178,8 +201,11 @@ hr {
     &.btn-warning {
         color: #fff;
     }
+
     &.btn-outline-warning:not(:disabled) {
-        &:hover, &:active {
+
+        &:hover,
+        &:active {
             color: #fff;
         }
     }
@@ -189,9 +215,12 @@ hr {
     background-color: $btn-secondary-bg;
     border-color: $btn-secondary-border;
     color: $btn-secondary-color;
+
     &:hover {
         background-color: #f5f5f5;
-    } // active state override
+    }
+
+    // active state override
     &:not(:disabled):not(.disabled):active,
     &:not(:disabled):not(.disabled).active,
     .show>&.dropdown-toggle {
@@ -201,23 +230,28 @@ hr {
 }
 
 .btn-outline-secondary {
-    border-color: $btn-secondary-border !important;
+    border-color: $btn-secondary-border  !important;
     color: $btn-secondary-color;
+
     &:hover {
         color: $btn-secondary-color;
         background-color: #f5f5f5 !important;
     }
+
     &:focus {
         box-shadow: 0 0 0 0.2rem rgba($btn-secondary-border, 0.5);
     }
 }
 
-span.btn { -webkit-appearance: none !important; }
+span.btn {
+    -webkit-appearance: none !important;
+}
 
 // FORMS
 .form-control {
     box-shadow: 0 0 0 #000 !important;
     font-size: 0.875rem; //14px
+
     &:focus {
         border-color: $input-focus-border-color;
     }
@@ -237,6 +271,7 @@ select.form-control-sm {
 .custom-control-label::after {
     top: 0.19rem;
 }
+
 .custom-control-label::before {
     border: 1px solid $gray;
 }
@@ -245,10 +280,12 @@ fieldset {
     padding-bottom: 20px;
     border-bottom: 1px dashed #eee;
     margin-bottom: 20px;
+
     &.last-child,
     &:last-child {
         border-bottom: 0;
     }
+
     .form-group {
         margin-bottom: 0;
     }
@@ -259,6 +296,7 @@ fieldset {
 }
 
 @include media-breakpoint-down(sm) {
+
     // Remove Input Shadows on iPad
     input[type="text"],
     input[type="email"],
@@ -278,7 +316,9 @@ fieldset {
     // Bottom align for column headings
     >thead>tr>th {
         border-bottom-width: 0;
-    } // Account for multiple tbody instances
+    }
+
+    // Account for multiple tbody instances
     >tbody+tbody {
         border-bottom-width: 1px;
     }
@@ -290,6 +330,7 @@ fieldset {
 
 .table-bordered {
     >thead>tr {
+
         >th,
         >td {
             border-bottom-width: 1px;
@@ -303,6 +344,7 @@ fieldset {
     border-radius: $border-radius-sm;
     border: 1px solid $progress-bg;
     background-color: #fff;
+
     .progress-bar {
         @include box-shadow(0 0 0 #000);
     }
@@ -315,6 +357,7 @@ fieldset {
     border-color: #eee;
     border-bottom: 2px solid $gray-light;
     border-radius: $border-radius-sm;
+
     .popover-title {
         border: 0;
     }
@@ -337,6 +380,7 @@ fieldset {
     padding: 0.3125rem 0;
     box-shadow: rgba(0, 0, 0, 0.176) 0px 6px 12px;
     border-color: $dropdown-border-color;
+
     .dropdown-item {
         line-height: 1.52857143;
         padding: 0.1875rem 1.25rem;
@@ -349,6 +393,7 @@ fieldset {
 
 .navbar-top .navbar-nav>.active>a {
     color: #999;
+
     &:hover,
     &:focus {
         color: #d1d2d3;
@@ -358,6 +403,7 @@ fieldset {
 
 .navbar-default .navbar-nav .open .dropdown-menu>li>a {
     color: #666;
+
     &:hover,
     &:focus {
         color: #222;
@@ -369,11 +415,15 @@ fieldset {
     .carousel-indicators {
         bottom: 0;
     }
+
     .carousel-control {
+
         &.left,
         &.right {
             background-image: none;
-        } // Add support for font awesome
+        }
+
+        // Add support for font awesome
         em {
             position: absolute;
             top: 50%;
@@ -410,20 +460,39 @@ $value in $theme-colors {
 
 .badge-red {
     color: #fff;
-    background-color: #FD4233; }
-    a.badge-info:hover, a.badge-info:focus {
-      color: #fff;
-      background-color: #FD4233; }
-    a.badge-info:focus, a.badge-info.focus {
-      outline: 0;
-      box-shadow: 0 0 0 0.2rem #FD4233; }
-
-      .badge-green {
-        color: #fff;
-        background-color: #1EA457; }
-        a.badge-info:hover, a.badge-info:focus {
-          color: #fff;
-          background-color: #1EA457; }
-        a.badge-info:focus, a.badge-info.focus {
-          outline: 0;
-          box-shadow: 0 0 0 0.2rem #1EA457; }
+    background-color: #FD4233;
+}
+
+a.badge-info:hover,
+a.badge-info:focus {
+    color: #fff;
+    background-color: #FD4233;
+}
+
+a.badge-info:focus,
+a.badge-info.focus {
+    outline: 0;
+    box-shadow: 0 0 0 0.2rem #FD4233;
+}
+
+.badge-green {
+    color: #fff;
+    background-color: #1EA457;
+}
+
+a.badge-info:hover,
+a.badge-info:focus {
+    color: #fff;
+    background-color: #1EA457;
+}
+
+a.badge-info:focus,
+a.badge-info.focus {
+    outline: 0;
+    box-shadow: 0 0 0 0.2rem #1EA457;
+}
+
+
+.cursor-pointer {
+    cursor: pointer;
+}

+ 16 - 0
styles/bootstrap/_buttons.scss

@@ -224,6 +224,22 @@ input[type="button"] {
   }
 }
 
+.btn-labeled-4 {
+  border: #3e3a8e solid 2px;
+  padding-top: 0;
+  padding-bottom: 0;
+  margin-top: 3%;
+  color: #3e3a8e;
+  background: white;
+  transition: ease background-color 250ms;
+
+  &:hover {
+    background-color: #e9e8e8;
+    opacity: 0.9;
+    color: #3e3a8e;
+  }
+}
+
 .btn-labeled-3 {
   border: #3e3a8e solid 2px;
   padding-top: 0;

+ 50 - 29
styles/bootstrap/_card.scss

@@ -14,12 +14,12 @@
   border: $card-border-width solid $card-border-color;
   @include border-radius($card-border-radius);
 
-  > hr {
+  >hr {
     margin-right: 0;
     margin-left: 0;
   }
 
-  > .list-group {
+  >.list-group {
     border-top: inherit;
     border-bottom: inherit;
 
@@ -36,8 +36,8 @@
 
   // Due to specificity of the above selector (`.card > .list-group`), we must
   // use a child selector here to prevent double borders.
-  > .card-header + .list-group,
-  > .list-group + .card-footer {
+  >.card-header+.list-group,
+  >.list-group+.card-footer {
     border-top: 0;
   }
 }
@@ -71,7 +71,7 @@
     text-decoration: none;
   }
 
-  + .card-link {
+  +.card-link {
     margin-left: $card-spacer-x;
   }
 }
@@ -88,9 +88,7 @@
   border-bottom: $card-border-width solid $card-border-color;
 
   &:first-child {
-    @include border-radius(
-      $card-inner-border-radius $card-inner-border-radius 0 0
-    );
+    @include border-radius($card-inner-border-radius $card-inner-border-radius 0 0);
   }
 }
 
@@ -101,9 +99,7 @@
   border-top: $card-border-width solid $card-border-color;
 
   &:last-child {
-    @include border-radius(
-      0 0 $card-inner-border-radius $card-inner-border-radius
-    );
+    @include border-radius(0 0 $card-inner-border-radius $card-inner-border-radius );
   }
 }
 
@@ -187,23 +183,25 @@
 //
 
 .card-group {
+
   // The child selector allows nested `.card` within `.card-group`
   // to display properly.
-  > .card {
+  >.card {
     margin-bottom: $card-group-margin;
   }
 
   @include media-breakpoint-up(sm) {
     display: flex;
     flex-flow: row wrap;
+
     // The child selector allows nested `.card` within `.card-group`
     // to display properly.
-    > .card {
+    >.card {
       // Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4
       flex: 1 0 0%;
       margin-bottom: 0;
 
-      + .card {
+      +.card {
         margin-left: 0;
         border-left: 0;
       }
@@ -218,6 +216,7 @@
             // stylelint-disable-next-line property-disallowed-list
             border-top-right-radius: 0;
           }
+
           .card-img-bottom,
           .card-footer {
             // stylelint-disable-next-line property-disallowed-list
@@ -233,6 +232,7 @@
             // stylelint-disable-next-line property-disallowed-list
             border-top-left-radius: 0;
           }
+
           .card-img-bottom,
           .card-footer {
             // stylelint-disable-next-line property-disallowed-list
@@ -273,7 +273,7 @@
 .accordion {
   overflow-anchor: none;
 
-  > .card {
+  >.card {
     overflow: hidden;
 
     &:not(:last-of-type) {
@@ -285,7 +285,7 @@
       @include border-top-radius(0);
     }
 
-    > .card-header {
+    >.card-header {
       @include border-radius(0);
       margin-bottom: -$card-border-width;
     }
@@ -299,6 +299,7 @@
   // width: 830px;
   margin-bottom: 30px;
 }
+
 .card-title-1 {
   margin-left: 10px;
   padding: 10px;
@@ -306,6 +307,7 @@
   text-align: left;
   color: rgba(255, 255, 255, 0.9);
 }
+
 .border-radius-login {
   border-radius: 5px;
 }
@@ -318,29 +320,35 @@
   height: 45px;
   margin: 20px;
 }
+
 .warna-penjadwalan-block {
   height: 35px;
   width: 60px;
   margin-left: auto;
 }
+
 .home-1 {
   margin-left: 20px;
   margin-right: 10px;
   margin-top: 20px;
 }
-.home-1-1{
+
+.home-1-1 {
   margin-left: 20px;
   margin-right: 10px;
   margin-top: -40px;
 }
+
 .home-2 {
   margin-top: 10%;
 }
+
 @media screen and (max-width: 450px) {
   .txt-size {
     font-weight: 400;
     color: black;
   }
+
   .home-1 {
     margin: 0;
   }
@@ -349,43 +357,53 @@
 .card-over {
   overflow: auto;
 }
+
 .f-size {
   margin-left: 10px;
 }
+
 .w-40 {
   width: 100px;
 }
+
 .margin-botton-20 {
   margin-bottom: 20px;
 }
+
 .text-tahun {
   font-size: 20px;
   text-align: center;
 }
+
 .font-color-white {
   color: #ffffff;
 }
+
 .font-color-black {
   color: black;
 }
+
 .border-2 {
   border-width: 0.5px;
   border-color: rgb(124, 122, 122);
 }
-.cd-home-1{
+
+.cd-home-1 {
   display: inline;
   position: relative;
   // background-color: red;
   // min-width: 300px;
   float: left;
 }
-.cd-home-2{
-display: inline;
-// background-color: rgb(50, 0, 230);
-// min-width: 300px;
-float: right;
+
+.cd-home-2 {
+  display: inline;
+  // background-color: rgb(50, 0, 230);
+  // min-width: 300px;
+  float: right;
 }
-.dropzone-style-1{
+
+.dropzone-style-1 {
   // background-color: #9e9e9e;
   // width: 50px;
   padding-top: 10px;
@@ -394,21 +412,24 @@ float: right;
   border-radius: 5px;
   cursor: pointer;
 }
-.center-ver-hor{
+
+.center-ver-hor {
   display: flex;
   align-items: center;
   justify-content: center;
   height: 100%;
 }
 
-.invalid-mv:focus:invalid{
+.invalid-mv:focus:invalid {
   border: solid 1px red;
   // background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-exclamation-triangle' viewBox='0 0 16 16'%3E%3Cpath d='M7.938 2.016A.13.13 0 0 1 8.002 2a.13.13 0 0 1 .063.016.146.146 0 0 1 .054.057l6.857 11.667c.036.06.035.124.002.183a.163.163 0 0 1-.054.06.116.116 0 0 1-.066.017H1.146a.115.115 0 0 1-.066-.017.163.163 0 0 1-.054-.06.176.176 0 0 1 .002-.183L7.884 2.073a.147.147 0 0 1 .054-.057zm1.044-.45a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566z'/%3E%3Cpath d='M7.002 12a1 1 0 1 1 2 0 1 1 0 0 1-2 0zM7.1 5.995a.905.905 0 1 1 1.8 0l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995z'/%3E%3C/svg%3E") no-repeat 95% 50% ;
 }
-.invalid-mv:focus:valid{
+
+.invalid-mv:focus:valid {
   border: solid 1px green;
 }
-.getover{
+
+.getover {
   overflow: auto;
   font-size: 0.8rem;
-}
+}

+ 140 - 2
styles/bootstrap/_progress.scss

@@ -1,8 +1,13 @@
 // Disable animation if transitions are disabled
 @if $enable-transitions {
   @keyframes progress-bar-stripes {
-    from { background-position: $progress-height 0; }
-    to { background-position: 0 0; }
+    from {
+      background-position: $progress-height 0;
+    }
+
+    to {
+      background-position: 0 0;
+    }
   }
 }
 
@@ -45,3 +50,136 @@
     }
   }
 }
+
+
+.BA-logo {
+  width: 250px;
+  margin-left: auto;
+  margin-right: auto;
+  padding-bottom: 10px;
+}
+
+.BA-header {
+  font-family: "Times New Roman", Times, serif;
+  text-align: center;
+  padding-bottom: 20px;
+}
+
+.BA-div {
+  padding-top: 100px;
+}
+
+.BA-p p {
+  padding: 10px;
+}
+
+.BA-body {
+  font-family: "Times New Roman", Times, serif;
+  padding-top: 0px;
+  padding-left: 50px;
+  padding-right: 50px;
+
+}
+
+.demo {
+  border: 1px solid #C0C0C0;
+  border-collapse: collapse;
+  padding: 5px;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+.demo th {
+  border: 1px solid #C0C0C0;
+  padding: 5px;
+  background: #F0F0F0;
+  text-align: center;
+}
+
+.demo td {
+  border: 1px solid #C0C0C0;
+  padding: 5px;
+  height: 100px;
+  min-width: 200px;
+}
+
+.table-a {
+  border: 1px solid #C0C0C0;
+  border-collapse: collapse;
+  margin-top: 20px;
+  margin-bottom: 20px;
+  padding: 5px;
+  margin-left: -128px auto;
+  margin-right: auto;
+  table-layout: fixed;
+}
+
+.table-a th {
+  border: 1px solid #C0C0C0;
+  padding: 5px;
+  background: #F0F0F0;
+  text-align: center;
+}
+
+.table-a td {
+  border: 1px solid #C0C0C0;
+  padding: 5px;
+  word-wrap: break-word;
+  max-width: 150px;
+}
+
+#footer {
+  position: fixed;
+  width: 100%;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  text-align: center;
+  color: #979595;
+}
+
+////////////////////////////-----SuratBA_A
+
+// body {
+//   margin: 0;
+//   padding: 0;
+//   background-color: #FAFAFA;
+//   font: 12pt "Tahoma";
+// }
+
+// * {
+//   box-sizing: border-box;
+//   -moz-box-sizing: border-box;
+// }
+
+// .page {
+//   width: 21cm;
+//   min-height: 29.7cm;
+//   padding: 2cm;
+//   margin: 1cm auto;
+//   border: 1px #D3D3D3 solid;
+//   border-radius: 5px;
+//   background: white;
+//   box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
+// }
+
+// .subpage {
+//   padding: 1cm;
+//   border: 5px red solid;
+//   height: 256mm;
+//   outline: 2cm #FFEAEA solid;
+// }
+
+// @page {
+//   size: A4;
+//   margin: 0;
+// }
+
+// @media print {
+
+//   body,
+//   page[size="A4"] {
+//     margin: 0;
+//     box-shadow: 0;
+//   }
+// }