diff --git a/.husky/commit-msg b/.husky/commit-msg old mode 100644 new mode 100755 diff --git a/.husky/pre-commit b/.husky/pre-commit old mode 100644 new mode 100755 diff --git a/pages/instruktur/create.jsx b/pages/instruktur/create.jsx index b56d9ff435106fb8cea0c54823116436db54eb2d..8467aff1a7d4f20fac2466a2bd7ae552ad4160ef 100644 --- a/pages/instruktur/create.jsx +++ b/pages/instruktur/create.jsx @@ -52,7 +52,7 @@ const Create = () => { router.push("/") }}>Back</span> </div> - <h1 className="text-[#F875AA] font-extrabold text-5xl mb-20 text-center">Update Instruktur</h1> + <h1 className="text-[#F875AA] font-extrabold text-5xl mb-20 text-center">Create Instruktur</h1> <form className="w-2/3 mx-auto space-y-10 flex flex-col align-middle justify-evenly" onSubmit={(e) => { e.preventDefault() handleUpdate() diff --git a/pages/instruktur/edit/[id].jsx b/pages/instruktur/edit/[id].jsx index 9cd8bc65fe9cd1b80526e33e3db73b7893f0b80a..1296a98465b3682eba91377e3711f9eeacba49ac 100644 --- a/pages/instruktur/edit/[id].jsx +++ b/pages/instruktur/edit/[id].jsx @@ -77,7 +77,7 @@ const Edit = () => { router.push("/") }}>Back</span> </div> - <h1 className="text-[#F875AA] font-extrabold text-5xl mb-20 text-center">Update Instruktur</h1> + <h1 className="text-[#F875AA] font-extrabold text-5xl mb-20 text-center">Update Instruktur</h1> <form className="w-2/3 mx-auto space-y-10 flex flex-col align-middle justify-evenly" onSubmit={(e) => { e.preventDefault() handleUpdate() diff --git a/pages/kendaraan/create.jsx b/pages/kendaraan/create.jsx new file mode 100644 index 0000000000000000000000000000000000000000..ec74380fd0feec7f58b0f5dbc251f90944ae6e0d --- /dev/null +++ b/pages/kendaraan/create.jsx @@ -0,0 +1,119 @@ +import Template from "@/components/template" +import { useState } from "react" +import { toast } from "react-toastify" +import { useRouter } from "next/router" +const Create = () => { + const router = useRouter() + const [nomorKendaraan, setNomorKendaraan] = useState("") + const [namaKendaraan, setNamaKendaraan] = useState("") + const [jenisTransmisi, setJenisTransmisi] = useState("MATIC") + const [jumlahKilometer, setJumlahKilometer] = useState("") + const [tanggalTerakhirService, setTanggalTerakhirService] = useState("") + const [statusKetersediaan, setStatusKetersediaan] = useState("AVAILABLE") + const [statusKendaraan, setStatusKendaraan] = useState("READY") + + const handleUpdate = async () => { + const token = window.localStorage.getItem("token") + if (token === undefined || token === null) { + window.location.replace("/auth/login") + return + } + const body = JSON.stringify({ + nomorKendaraan, + namaKendaraan, + jenisTransmisi, + jumlahKilometer, + tanggalTerakhirService, + statusKetersediaan, + statusKendaraan + }) + const updateQuery = await fetch("https://rpl-backend-production.up.railway.app/v1/kendaraan/create", { + method: "POST", + headers: { + Authorization: token, + "Content-Type": "application/json" + }, + body + }).then(response => response).catch(() => null) + if (updateQuery === null) { + toast.error("Something went wrong..") + return + } + if (updateQuery.status !== 200) { + toast.error("Failed to create...") + return + } + toast.success("Successfully created!") + router.push("/kendaraan") + return; + } + return <> + <Template> + <main className="min-h-screen px-14 py-5 bg-[#FFF6F6]"> + <div className="w-full mb-2"> + <span className="text-[#F875AA] font-bold text-2xl hover:cursor-pointer" onClick={(e) => { + e.preventDefault() + router.push("/") + }}>Back</span> + </div> + <h1 className="text-[#F875AA] font-extrabold text-5xl mb-20 text-center">Create Kendaraan</h1> + <form className="w-2/3 mx-auto space-y-10 flex flex-col align-middle justify-evenly" onSubmit={(e) => { + e.preventDefault() + handleUpdate() + return; + }}> + <div className="flex flex-row align-middle justify-between"> + <span className="h-min my-auto font-bold text-lg">Nomor Plat Kendaraan</span> + <input value={nomorKendaraan} onChange={(e) => { + setNomorKendaraan(e.target.value) + }} type="text" required className="drop-shadow-xl w-2/4 p-2 rounded-xl" /> + </div> + <div className="flex flex-row align-middle justify-between"> + <span className="h-min my-auto font-bold text-lg">Nama Kendaraan</span> + <input value={namaKendaraan} onChange={(e) => { + setNamaKendaraan(e.target.value) + }} type="text" required className="drop-shadow-xl w-2/4 p-2 rounded-xl" /> + </div> + <div className="flex flex-row align-middle justify-between"> + <span className="h-min my-auto font-bold text-lg">Jenis Transmisi Kendaraan</span> + <select value={jenisTransmisi}> + <option value="MATIC">Matic</option> + <option value="MANUAL">Manual</option> + </select> + </div> + <div className="flex flex-row align-middle justify-between"> + <span className="h-min my-auto font-bold text-lg">Jumlah Kilometer Kendaraan</span> + <input value={jumlahKilometer} onChange={(e) => { + setJumlahKilometer(e.target.value) + }} type="tel" required className="drop-shadow-xl w-2/4 p-2 rounded-xl" /> + </div> + <div className="flex flex-row align-middle justify-between"> + <span className="h-min my-auto font-bold text-lg">Tanggal Terakhir Service Kendaraan</span> + <input value={tanggalTerakhirService} onChange={(e) => { + setTanggalTerakhirService(e.target.value) + }} type="text" required className="drop-shadow-xl w-2/4 p-2 rounded-xl" /> + </div> + <div className="flex flex-row align-middle justify-between"> + <span className="h-min my-auto font-bold text-lg">Status Ketersediaan Kendaraan</span> + <select value={statusKetersediaan}> + <option value="AVAILABLE">Available</option> + <option value="IN USE">In Use</option> + </select> + </div> + <div className="flex flex-row align-middle justify-between"> + <span className="h-min my-auto font-bold text-lg">Status Service Kendaraan</span> + <select value={statusKetersediaan}> + <option value="SERVICE">Service</option> + <option value="READY">Ready</option> + </select> + </div> + <input type="submit" className="bg-[#F875AA] px-8 py-3 text-xl font-bold text-white rounded-xl mx-auto" value={"Simpan"} /> + </form> + + </main> + </Template > + </> + +} + +export default Create \ No newline at end of file diff --git a/pages/kendaraan/edit/[id].jsx b/pages/kendaraan/edit/[id].jsx new file mode 100644 index 0000000000000000000000000000000000000000..db0ee2b07866e8001032c998cc320e746b2d5c36 --- /dev/null +++ b/pages/kendaraan/edit/[id].jsx @@ -0,0 +1,146 @@ +import Template from "@/components/template" +import { useEffect, useState } from "react" +import { toast } from "react-toastify" +import { useRouter } from "next/router" +const Edit = () => { + const router = useRouter() + const [nomorKendaraan, setNomorKendaraan] = useState("") + const [namaKendaraan, setNamaKendaraan] = useState("") + const [jenisTransmisi, setJenisTransmisi] = useState("MATIC") + const [jumlahKilometer, setJumlahKilometer] = useState("") + const [tanggalTerakhirService, setTanggalTerakhirService] = useState("") + const [statusKetersediaan, setStatusKetersediaan] = useState("AVAILABLE") + const [statusKendaraan, setStatusKendaraan] = useState("READY") + + const handleUpdate = async () => { + const token = window.localStorage.getItem("token") + if (token === undefined || token === null) { + window.location.replace("/auth/login") + return + } + const body = JSON.stringify({ + jumlahKilometer, + tanggalTerakhirService, + statusKetersediaan, + statusKendaraan + }) + const updateQuery = await fetch("https://rpl-backend-production.up.railway.app/v1/kendaraan/update/" + router.query.id, { + method: "PATCH", + headers: { + Authorization: token, + "Content-Type": "application/json" + }, + body + }).then(response => response).catch(() => null) + if (updateQuery === null) { + toast.error("Someting went wrong..") + return + } + if (updateQuery.status !== 200) { + toast.error("Failed to update...") + return + } + toast.success("Successfully updated!") + router.push("/kendaraan") + return; + } + + useEffect(() => { + const token = window.localStorage.getItem("token") + if (token === undefined || token === null) { + window.location.replace("/auth/login") + return + } + fetch("https://rpl-backend-production.up.railway.app/v1/kendaraan/list/" + router.query.id, { + method: "GET", + headers: { + "Authorization": token + } + }).then(async response => { + if (response.status !== 200) { + toast.error("Failed to retrieve items") + return + } + const responsejson = await response.json() + setNomorKendaraan(responsejson.data.nomorKendaraan) + setNamaKendaraan(responsejson.data.namaKendaraan) + setJenisTransmisi(responsejson.data.jenisTransmisi) + setJumlahKilometer(responsejson.data.jumlahKilometer) + setTanggalTerakhirService(responsejson.data.tanggalTerakhirService) + setStatusKetersediaan(responsejson.data.statusKetersediaan) + setStatusKendaraan(responsejson.data.statusKendaraan) + }) + //eslint-disable-next-line + }, []) + return <> + <Template> + <main className="min-h-screen px-14 py-5 bg-[#FFF6F6]"> + <div className="w-full mb-2"> + <span className="text-[#F875AA] font-bold text-2xl hover:cursor-pointer" onClick={(e) => { + e.preventDefault() + router.push("/") + }}>Back</span> + </div> + <h1 className="text-[#F875AA] font-extrabold text-5xl mb-20 text-center">Update Kendaraan</h1> + <form className="w-2/3 mx-auto space-y-10 flex flex-col align-middle justify-evenly" onSubmit={(e) => { + e.preventDefault() + handleUpdate() + return; + }}> + <div className="flex flex-row align-middle justify-between"> + <span className="h-min my-auto font-bold text-lg">Nomor Plat Kendaraan</span> + <input disabled value={nomorKendaraan} type="text" required className="drop-shadow-xl w-2/4 p-2 rounded-xl" /> + </div> + <div className="flex flex-row align-middle justify-between"> + <span className="h-min my-auto font-bold text-lg">Nama Kendaraan</span> + <input disabled value={namaKendaraan} type="text" required className="drop-shadow-xl w-2/4 p-2 rounded-xl" /> + </div> + <div className="flex flex-row align-middle justify-between"> + <span className="h-min my-auto font-bold text-lg">Jenis Transmisi Kendaraan</span> + <select disabled value={statusKetersediaan}> + <option value="MATIC">Matic</option> + <option value="MANUAL">Manual</option> + </select> + </div> + <div className="flex flex-row align-middle justify-between"> + <span className="h-min my-auto font-bold text-lg">Jumlah Kilometer Kendaraan</span> + <input value={jumlahKilometer} onChange={(e) => { + setJumlahKilometer(e.target.value) + }} type="tel" required className="drop-shadow-xl w-2/4 p-2 rounded-xl" /> + </div> + <div className="flex flex-row align-middle justify-between"> + <span className="h-min my-auto font-bold text-lg">Tanggal Terakhir Service Kendaraan</span> + <input value={tanggalTerakhirService} onChange={(e) => { + setTanggalTerakhirService(e.target.value) + }} type="text" required className="drop-shadow-xl w-2/4 p-2 rounded-xl" /> + </div> + <div className="flex flex-row align-middle justify-between"> + <span className="h-min my-auto font-bold text-lg">Tanggal Terakhir Service Kendaraan</span> + <input value={tanggalTerakhirService} onChange={(e) => { + setTanggalTerakhirService(e.target.value) + }} type="text" required className="drop-shadow-xl w-2/4 p-2 rounded-xl" /> + </div> + <div className="flex flex-row align-middle justify-between"> + <span className="h-min my-auto font-bold text-lg">Status Ketersediaan Kendaraan</span> + <select value={statusKetersediaan}> + <option value="AVAILABLE">Available</option> + <option value="IN USE">In Use</option> + </select> + </div> + <div className="flex flex-row align-middle justify-between"> + <span className="h-min my-auto font-bold text-lg">Status Service Kendaraan</span> + <select value={statusKetersediaan}> + <option value="SERVICE">Service</option> + <option value="READY">Ready</option> + </select> + </div> + <input type="submit" className="bg-[#F875AA] px-8 py-3 text-xl font-bold text-white rounded-xl mx-auto" value={"Simpan"} /> + </form> + + </main> + </Template > + </> + +} + +export default Edit \ No newline at end of file diff --git a/pages/kendaraan/index.jsx b/pages/kendaraan/index.jsx new file mode 100644 index 0000000000000000000000000000000000000000..5f9b2ec950d69db347e44b2e0d6f203caff2cb53 --- /dev/null +++ b/pages/kendaraan/index.jsx @@ -0,0 +1,168 @@ +import Template from "@/components/template" +import { useEffect, useState } from "react" +import { toast } from "react-toastify" +import { useRouter } from "next/router" +const Index = () => { + const [rows, setRows] = useState([]) + const router = useRouter() + const [deleteToggle, setDeleteToggle] = useState(null) + const [currentPage, setCurrentPage] = useState(1); + const [isLastPage, setLastPage] = useState(false) + + const getNextPage = async (page) => { + const token = window.localStorage.getItem("token") + if (token === undefined || token === null) { + window.location.replace("/auth/login") + return; + } + const getItems = await fetch("https://rpl-backend-production.up.railway.app/v1/kendaraan/list?page=" + (page), { + method: "GET", + headers: { + Authorization: token + } + }).then(response => response).catch(() => null) + if (getItems === null) { + toast.error("Something went wrong..") + return; + } + if (getItems.status !== 200) { + toast.error("Unable to get more items!") + return + } + const responsejson = await getItems.json(); + setLastPage(responsejson.data.length < 10) + setRows(responsejson.data); + return + } + const handleDelete = async () => { + const token = window.localStorage.getItem("token") + if (token === undefined || token === null) { + window.location.replace("/auth/login") + return + } + const deleteRequest = await fetch("https://rpl-backend-production.up.railway.app/v1/kendaraan/delete/" + deleteToggle, { + method: "DELETE", + headers: { + Authorization: token + } + }).then(response => response).catch(() => null) + setDeleteToggle(null) + if (deleteRequest === null) { + toast.error("Something went wrong..."); + return; + } + if (deleteRequest.status !== 200) { + toast.error("Failed to delete.."); + return; + } + toast.success("Successfully deleted!"); + router.reload(); + return; + } + useEffect(() => { + const token = window.localStorage.getItem("token") + if (token === undefined || token === null) { + window.location.replace("/auth/login") + return + } + fetch("https://rpl-backend-production.up.railway.app/v1/kendaraan/list", { + method: "GET", + headers: { + "Authorization": token + } + }).then(async response => { + if (response.status !== 200) { + toast.error("Failed to retrieve items") + return + } + const responsejson = await response.json() + setRows(responsejson.data) + }) + }, []) + return <> + <Template> + <main className="min-h-screen px-14 py-5 bg-[#FFF6F6]"> + <div className="w-full mb-2"> + <span className="text-[#F875AA] font-bold text-2xl hover:cursor-pointer" onClick={(e) => { + e.preventDefault() + router.push("/") + }}>Back</span> + </div> + <div className="flex flex-row align-middle justify-between"> + <h1 className="text-[#F875AA] font-extrabold text-5xl mb-8">Data Kendaraan</h1> + <button onClick={(e) => { + e.preventDefault(); + router.push("/kendaraan/create") + }} className="bg-[#F875AA] p-4 text-lg font-bold text-white rounded-3xl">Create</button> + </div> + <table className="w-full text-center border-spacing-3 border-separate"> + <thead> + <tr> + <th className="bg-[#F875AA] p-2 border border-[#F875AA]">Nomor Plat Kendaraan</th> + <th className="bg-[#F875AA] p-2 border border-[#F875AA]">Nama Kendaraan</th> + <th className="bg-[#F875AA] p-2 border border-[#F875AA]">Jenis Transmisi Kendaraan</th> + <th className="bg-[#F875AA] p-2 border border-[#F875AA]">Jumlah Kilometer Kendaraan</th> + <th className="bg-[#F875AA] p-2 border border-[#F875AA]">Tanggal Terakhir Service Kendaraan</th> + <th className="bg-[#F875AA] p-2 border border-[#F875AA]">Status Ketersediaan Kendaraan</th> + <th className="bg-[#F875AA] p-2 border border-[#F875AA]">Status Service Kendaraan</th> + <th className=""></th> + </tr> + </thead> + <tbody> + {rows.map((row, index) => { + return <tr key={row.nomorKendaraan}> + <td className="p-6 border border-[#F875AA] bg-white">{row.nomorKendaraan}</td> + <td className="p-6 border border-[#F875AA] bg-white">{row.namaKendaraan}</td> + <td className="p-6 border border-[#F875AA] bg-white">{row.jenisTransmisi}</td> + <td className="p-6 border border-[#F875AA] bg-white">{row.jumlahKilometer}</td> + <td className="p-6 border border-[#F875AA] bg-white">{row.tanggalTerakhirService}</td> + <td className="p-6 border border-[#F875AA] bg-white">{row.statusKetersediaan}</td> + <td className="p-6 border border-[#F875AA] bg-white">{row.statusKendaraan}</td> + <td className="px-2 flex flex-col align-middle justify-evenly space-y-2 "> + <button className="bg-[#AEDEFC] p-1 rounded-lg" onClick={(e) => { + e.preventDefault(); + router.push("/kendaraan/edit/" + row.nomorKendaraan) + return; + }}>Update</button> + <button data-modal-target="popup-modal" data-modal-toggle="popup-modal" className="bg-[#FFDFDF] p-1 rounded-lg" onClick={(e) => { + e.preventDefault() + setDeleteToggle(row.nomorKendaraan) + }}>Delete</button> + </td> + </tr> + })} + </tbody> + </table> + <div className="flex flex-row align-middle justify-around"> + <button className="bg-red-400 p-5 rounded-2xl text-white font-bold" disabled={currentPage === 1} onClick={() => { + getNextPage(currentPage - 1) + setCurrentPage(page => page - 1) + }}>Prev</button> + <span className="h-min my-auto font-bold">Page {currentPage}</span> + <button className="bg-blue-400 p-5 rounded-2xl text-white font-bold" disabled={isLastPage} onClick={() => { + getNextPage(currentPage + 1) + setCurrentPage(page => page + 1) + }}>Next</button> + </div> + </main> + {deleteToggle !== null && <div className="left-0 top-0 fixed w-screen h-screen bg-white bg-opacity-80 p-20 flex flex-col align-middle justify-center"> + <div className="w-1/2 mx-auto space-y-5"> + <h1 className="text-center p-10 bg-[#FFDFDF] border-2 border-[#F875AA] rounded-xl font-bold text-xl">Apakah anda yakin akan menghapus data kendaraan?</h1> + <div className="space-x-5 flex flex-row align-middle justify"> + <button className="p-3 rounded-xl w-full bg-[#FFDFDF] border-2 border-[#F875AA]" onClick={(e) => { + e.preventDefault(); + handleDelete() + }}>Delete</button> + <button className="p-3 rounded-xl w-full bg-[#FFDFDF] border-2 border-[#F875AA]" onClick={(e) => { + e.preventDefault() + setDeleteToggle(null) + }}>Cancel</button> + </div> + </div> + </div>} + </Template > + </> + +} + +export default Index \ No newline at end of file