MIF_E31212365/resources/js/Pages/Admin/Kuis.jsx

308 lines
12 KiB
JavaScript

import React, { useState } from "react";
import AdminLayout from "./Layout/AdminLayout";
import { MdOutlineFileUpload } from "react-icons/md";
import { Link } from "@inertiajs/react";
import HitApi from "../../Utils/HitApi";
import Swal from "sweetalert2";
const Kuis = (props) => {
const { materi, soal } = props;
const [form, setForm] = useState({
soal: soal.pertanyaan,
gambar_soal: soal.gambar_soal,
jawaban: soal.jawaban,
});
const handleSave = () => {
// buatkan datanya ke formdata
Swal.fire({
title: "Konfirmasi",
text: "Apakah anda yakin ingin menyimpan data?",
icon: "warning",
showCancelButton: true,
confirmButtonColor: "#3085d6",
cancelButtonColor: "#d33",
confirmButtonText: "Ya",
}).then((result) => {
if (result.isConfirmed) {
const formData = new FormData();
formData.append("id", soal.id);
formData.append("soal", form.soal);
formData.append("gambar_soal", form.gambar_soal);
form.jawaban.forEach((item, i) => {
formData.append("id_jawaban[]", item.id);
formData.append("jawaban[]", item.jawaban);
formData.append(
`gambar_jawaban[${i}]`,
item.gambar_jawaban
);
formData.append("benar[]", item.benar);
});
Swal.fire({
title: "Loading",
html: '<div class="body-loading"><div class="loadingspinner"></div></div>', // add html attribute if you want or remove
allowOutsideClick: false,
showConfirmButton: false,
});
HitApi({
url: "/api/v1/quiz/save",
method: "POST",
body: formData,
isFormData: true,
onSuccess: () => {
Swal.fire(
"Berhasil",
"Data berhasil disimpan",
"success"
);
},
onError: () => {
// Swal.fire("Gagal", "Data gagal ditambahkan", "error");
Swal.close();
},
});
}
});
};
const state = {
form,
setForm,
};
const [previewImage, setPreviewImage] = useState();
return (
<AdminLayout title="Materi">
<div className="flex flex-col md:flex-row gap-6 relative ">
<div className="flex flex-col flex-1 order-2 md:order-1">
<h1 className="font-semibold text-lg py-2">Input Soal</h1>
<textarea
className="textarea textarea-bordered h-[150px] w-full mt-2"
placeholder="Soal"
value={form.soal}
onChange={(e) => {
setForm({ ...form, soal: e.target.value });
}}
></textarea>
<div className="border-2 relative flex flex-col items-center rounded-md justify-center mt-4 min-h-[200px]">
<img
className="absolute w-full h-full object-cover"
src={
previewImage
? URL.createObjectURL(previewImage)
: `/uploads/soal/${form.gambar_soal}`
}
alt="Soal"
onLoad={(e) => {
e.target.style.display = "block";
}}
onError={(e) => {
e.target.style.display = "none";
}}
/>
<input
onChange={(e) => {
setPreviewImage(e.target.files[0]);
setForm({
...form,
gambar_soal: e.target.files[0],
});
}}
className="flex w-full h-full opacity-0 absolute"
type="file"
name=""
id=""
/>
<MdOutlineFileUpload size={40} />
<p>Upload Gambar</p>
</div>
<h1 className="font-semibold text-lg py-2 mt-4">Jawaban</h1>
{form.jawaban.map((item, index) => (
<CardJawaban
id={item.id}
state={state}
jawaban={item.jawaban}
isTrue={item.benar}
key={index}
gambar={item.gambar_jawaban}
/>
))}
<div className="flex gap-4 justify-end">
{/* <button className="btn btn-error mt-6 w-fit">
Delete
</button> */}
<button
onClick={() => handleSave()}
className="btn btn-primary mt-6 w-fit"
>
Save
</button>
</div>
</div>
<div className="md:sticky md:top-12 md:right-0 h-fit order-1 md:order-2">
<div className="md:h-[40px]"></div>
<div className=" w-full md:w-[300px] lg:w-[400px] border-2 flex p-4 flex-col h-fit ">
<h1 className="font-semibold text-lg">No Soal</h1>
<div className="grid grid-cols-4 gap-3 mt-6">
{materi.kuis.map((item, index) => {
return (
<Link
key={index}
href={`/admin/quiz/input/${
materi.id
}?soal=${index + 1}`}
>
<CardNoSoal no={index + 1} />
</Link>
);
})}
<Link
href={`/admin/quiz/input/${materi.id}?soal=${
materi.kuis.length + 1
}`}
>
<CardNoSoal isBaru no={"Tambah Soal"} />
</Link>
</div>
</div>
</div>
</div>
</AdminLayout>
);
};
const CardNoSoal = ({ no = 1, isBaru = false }) => {
return (
<div
className={`${
isBaru ? "bg-gray-300 text-black" : "bg-primary text-white"
} flex items-center justify-center text-xs py-4 rounded-md px-3 text-center h-full`}
>
{no}
</div>
);
};
const CardJawaban = ({ id, jawaban, gambar, isTrue = false, state }) => {
const { form, setForm } = state;
const [preview, setPreview] = useState();
return (
<label
className="flex flex-row gap-4 border-2 rounded-md px-4 py-6 my-4"
htmlFor=""
>
<div className="py-4">
<input
onChange={(e) => {
{
setForm({
...form,
jawaban: [
...form.jawaban.map((item) => {
if (item.id == e.target.value) {
return {
...item,
benar: 1,
};
} else {
return {
...item,
benar: 0,
};
}
}),
],
});
}
}}
type="radio"
value={id}
name="radio-7"
className="radio radio-info"
checked={isTrue}
/>
</div>
<div className="flex flex-col w-full">
<textarea
className="textarea w-full mt-2 ouli"
value={jawaban}
onChange={(e) => {
{
setForm({
...form,
jawaban: [
...form.jawaban.map((item) => {
if (item.id == id) {
return {
...item,
jawaban: e.target.value,
};
} else {
return item;
}
}),
],
});
}
}}
placeholder="Jawaban"
></textarea>
<div className="flex flex-col relative items-center bg-gray-100 rounded-md justify-center mt-4 min-h-[200px]">
<img
className="absolute w-full h-full object-cover"
src={
preview
? URL.createObjectURL(preview)
: `/uploads/jawaban/${gambar}`
}
alt="Jawaban"
onLoad={(e) => {
e.target.style.display = "block";
}}
onError={(e) => {
e.target.style.display = "none";
}}
/>
<input
onChange={(e) => {
setPreview(e.target.files[0]);
setForm({
...form,
jawaban: [
...form.jawaban.map((item) => {
if (item.id == id) {
return {
...item,
gambar_jawaban:
e.target.files[0],
};
} else {
return item;
}
}),
],
});
}}
className="flex w-full h-full opacity-0 absolute"
type="file"
name=""
id=""
/>
<MdOutlineFileUpload size={40} />
<p>Upload Gambar</p>
</div>
</div>
</label>
);
};
export default Kuis;