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/components/template.jsx b/components/template.jsx index b318f84b66350a373d0a424934334b57565ddb1e..d1c5d5e5f8bcbfcd3b7fecfa7b2bc9f878095125 100644 --- a/components/template.jsx +++ b/components/template.jsx @@ -12,7 +12,7 @@ const Template = ({ children }) => { const handleLogout = (e) => { e.preventDefault(); window.localStorage.removeItem("token"); - window.location.reload(); + window.location.replace("/"); } useEffect(() => { const token = window.localStorage.getItem("token") @@ -22,6 +22,9 @@ const Template = ({ children }) => { if (response.status !== 200) return null; const responsejson = await response.json(); setUser(responsejson.data) + }).catch(error => { + console.error(error) + return }) }, []) return <> diff --git a/components/templatenofooter.jsx b/components/templatenofooter.jsx index 5df5c9fd35286ab14d1e7e46c3042fdd50b05d9e..7682e9376d7a36fe50d81138698b3ecdc67affb6 100644 --- a/components/templatenofooter.jsx +++ b/components/templatenofooter.jsx @@ -12,7 +12,7 @@ const Template = ({ children }) => { const handleLogout = (e) => { e.preventDefault(); window.localStorage.removeItem("token"); - window.location.reload(); + window.location.replace("/"); } useEffect(() => { const token = window.localStorage.getItem("token") diff --git a/pages/adminkursus/create.jsx b/pages/adminkursus/create.jsx index 181f2ebe287255c4d5e1a5ce58f289ccb2e101b8..ee0e9dc84b45daf23f7f9a858c34f2a26a52e3b0 100644 --- a/pages/adminkursus/create.jsx +++ b/pages/adminkursus/create.jsx @@ -44,7 +44,7 @@ const Create = () => { <div className="w-full mb-2"> <span className="text-[#F875AA] font-bold text-2xl hover:cursor-pointer" onClick={(e) => { e.preventDefault() - router.back() + router.replace('/adminkursus') }}>Back</span> </div> <h1 className="text-[#F875AA] font-extrabold text-5xl mb-20 text-center">Create Admin Kursus</h1> @@ -64,7 +64,7 @@ const Create = () => { <span className="h-min my-auto font-bold text-lg">Password</span> <input value={password} onChange={(e) => { setpassword(e.target.value) - }} type="text" required className="drop-shadow-xl w-2/3 p-2 rounded-xl" /> + }} type="password" required className="drop-shadow-xl w-2/3 p-2 rounded-xl" /> </div> <input type="submit" className="bg-[#F875AA] px-8 py-3 text-xl font-bold text-white rounded-xl mx-auto" value={"Simpan"} /> diff --git a/pages/adminkursus/edit/[id].jsx b/pages/adminkursus/edit/[id].jsx index a8d3541d3ac877acf4d7442b0dc28cf55c66a15a..c16f742770e62dd63f2417a0f03e12e42df72e49 100644 --- a/pages/adminkursus/edit/[id].jsx +++ b/pages/adminkursus/edit/[id].jsx @@ -70,7 +70,7 @@ const Edit = () => { <div className="w-full mb-2"> <span className="text-[#F875AA] font-bold text-2xl hover:cursor-pointer" onClick={(e) => { e.preventDefault() - router.back() + router.replace("/adminkursus") }}>Back</span> </div> <h1 className="text-[#F875AA] font-extrabold text-5xl mb-20 text-center">Update Admin Kursus</h1> @@ -87,13 +87,13 @@ const Edit = () => { <span className="h-min my-auto font-bold text-lg">Username</span> <input value={username} onChange={(e) => { setusername(e.target.value) - }} type="text" required className="drop-shadow-xl w-2/3 p-2 rounded-xl" /> + }} type="text" className="drop-shadow-xl w-2/3 p-2 rounded-xl" /> </div> <div className="flex flex-row align-middle justify-between"> <span className="h-min my-auto font-bold text-lg">Password</span> <input value={password} onChange={(e) => { setpassword(e.target.value) - }} type="text" required className="drop-shadow-xl w-2/3 p-2 rounded-xl" /> + }} type="password" className="drop-shadow-xl w-2/3 p-2 rounded-xl" /> </div> <input type="submit" className="bg-[#F875AA] px-8 py-3 text-xl font-bold text-white rounded-xl mx-auto" value={"Simpan"} /> diff --git a/pages/adminkursus/index.jsx b/pages/adminkursus/index.jsx index 65d72e293009d24447a1b1620a067822785d4f25..fe35a556b3e673196e4a2820e1931914954a3bd7 100644 --- a/pages/adminkursus/index.jsx +++ b/pages/adminkursus/index.jsx @@ -65,7 +65,7 @@ const Index = () => { window.location.replace("/auth/login") return } - fetch("https://rpl-backend-production.up.railway.app/v1/adminkursus/list/", { + fetch("https://rpl-backend-production.up.railway.app/v1/adminkursus/list", { method: "GET", headers: { "Authorization": token @@ -85,7 +85,7 @@ const Index = () => { <div className="w-full mb-2"> <span className="text-[#F875AA] font-bold text-2xl hover:cursor-pointer" onClick={(e) => { e.preventDefault() - router.back() + router.replace("/dashboard/owner") }}>Back</span> </div> <div className="flex flex-row align-middle justify-between"> @@ -105,7 +105,7 @@ const Index = () => { </tr> </thead> <tbody> - {rows.map((row, index) => { + {rows.filter(row => row.user_id !== 10000).map((row, index) => { return <tr key={row.user_id}> <td className="p-6 border border-[#F875AA] bg-white">{row.user_id}</td> <td className="p-6 border border-[#F875AA] bg-white">{row.username}</td> diff --git a/pages/auth/login.jsx b/pages/auth/login.jsx index 6f103573014c6767f1ce363d09c073f8feaeed65..078eab6da911720f0715d1652bfafb4de44ebc61 100644 --- a/pages/auth/login.jsx +++ b/pages/auth/login.jsx @@ -1,6 +1,7 @@ import { useState } from "react" import { toast } from "react-toastify" import { useRouter } from "next/router" +import Image from "next/image" const Login = () => { const [username, setUsername] = useState("") @@ -8,75 +9,70 @@ const Login = () => { const router = useRouter() return ( - <main className="min-h-screen px-14 py-7 bg-[#FFF6F6]"> - - <div className="w-full mb-2"> - <img className="w-[352px] h-[352px] left-[580px] top-[168px] absolute" src="/logo.png" /> - <div className="w-[693px] h-[124px] left-[409px] top-[106px] absolute text-center text-pink-400 text-[40px] font-extrabold font-'Poppins'">Log In</div> - <div className="w-[130px] h-[33px] left-[427px] top-[559px] absolute text-pink-400 text-xl font-extrabold font-'Poppins'">Username</div> - <div className="w-[58px] h-[27px] left-[72px] top-[48px] absolute text-pink-400 text-xl font-extrabold font-'Poppins'"> - <span className="text-[#F875AA] font-bold text-2xl hover:cursor-pointer" onClick={(e) => { - e.preventDefault() - router.back() - }}>Back</span> - </div> - <div className="w-[130px] h-[33px] left-[427px] top-[654px] absolute text-pink-400 text-xl font-extrabold font-'Poppins'">Password</div> - <div className="w-[252px] h-[55px] left-[630px] top-[750px] absolute"> + <main className="min-h-screen px-14 py-7 bg-[#FFF6F6] flex flex-col"> + <div className="fex flex-row w-full"> + <button className="text-xl text-[#F875AA] font-extrabold" onClick={ + ()=>router.replace("/")}>Back</button> </div> - <img className="w-[22px] h-[22px] left-[38px] top-[53px] absolute" src="/back.png" /> - </div> - - <form onSubmit={(e) => { + <div className="flex flex-col w-1/2 align-middle justify-around mx-auto my-auto"> + <h1 className="text-center font-extrabold text-5xl text-[#F875AA]">Log In</h1> + <div className="w-full"><Image src={"/logo.png"} width={400} height={400} alt="Main Logo" className="mx-auto"/></div> + <form className="flex flex-col align-middle justify-evenly space-y-8" onSubmit={(e) => { e.preventDefault() const requestBody = JSON.stringify({ - username, password + username,password }) fetch("https://rpl-backend-production.up.railway.app/v1/auth/login", { - method: "POST", - body: requestBody, - headers: { - "Content-Type": "application/json" - } - }).then(async (response) => { - if (response.status !== 200) { - toast.error("Failed to login..") - return - } - const responsejson = await response.json(); - const type = responsejson.data.type - const token = responsejson.data.token - window.localStorage.setItem("token", `${type} ${token}`) - - - fetch("https://rpl-backend-production.up.railway.app/v1/auth/verify/" + token,) - .then(async (response) => { - const responsejson = await response.json(); - if (responsejson.data.tipe_user === "OWNER"){ - router.push("/dashboard/owner") - return - } - if (responsejson.data.tipe_user === "ADMIN"){ - router.push("/dashboard/admin") + method: "POST", + body: requestBody, + headers: { + "Content-Type": "application/json" + } + }).then(async (response) => { + if (response.status !== 200){ + toast.error("Failed to login..") return - } - }) - - }).catch(() => { - toast.error("Something went wrong..") - }) - }} > - <input type="text" placeholder=" Username" required className="w-4/12 h-14 left-[602px] top-[536px] absolute bg-white rounded-[15px] p-3 shadow border border-red-100" value={username} onChange={(e) => { - setUsername(e.target.value) - }} /> - <input type="password" placeholder=" Password" required className="w-4/12 h-14 left-[602px] top-[643px] absolute bg-white rounded-[15px] p-3 shadow border border-red-100" value={password} onChange={(e) => { - setPassword(e.target.value) - }} /> - <input type="submit" className="w-[252px] h-[55px] left-[630px] top-[750px] absolute w-[252px] h-[55px] left-0 top-0 absolute bg-pink-400 rounded-[15px] w-[168.56px] h-[29.40px] left-[41.72px] top-[11.38px] absolute text-center text-white text-2xl font-bold font-'Poppins' hover:cursor-pointer" value ={"Log In"}/> + } + const responsejson = await response.json(); + const type = responsejson.data.type + const token = responsejson.data.token + window.localStorage.setItem("token", `${type} ${token}`) + fetch("https://rpl-backend-production.up.railway.app/v1/auth/verify/" + token,) + .then(async(response) =>{ + const responsejson = await response.json(); + if (responsejson.data.tipe_user === "OWNER"){ + router.push("/dashboard/owner") + return + } + if (responsejson.data.tipe_user === "ADMIN"){ + router.push("/dashboard/admin") + return + } + }) + }).catch(() => { + toast.error("Something went wrong..") + }) + + }}> + <div className="flex flex-row align-middle justify-between "> + <span className="h-min my-auto font-extrabold text-[#F875AA] text-xl">Username</span> + <input className="w-2/3 drop-shadow-lg p-3 rounded-xl shadow shadow-[#FFDFE0]" type="text" placeholder="Username" required value={username} onChange={(e) => { + setUsername(e.target.value) + }}/> + </div> + <div className="flex flex-row align-middle justify-between "> + <span className="h-min my-auto font-extrabold text-[#F875AA] text-xl">Password</span> + <input className="w-2/3 drop-shadow-lg p-3 rounded-xl shadow shadow-[#FFDFE0]" type="password" placeholder="Password" required value={password} onChange={(e) => { + setPassword(e.target.value) + }}/> + </div> + <input type="submit" value={"Log In"} className="w-min px-20 py-3 mx-auto bg-pink-400 rounded-xl text-white font-bold text-2xl hover:cursor-pointer"/> </form> + + </div> </main> ) - } export default Login \ No newline at end of file diff --git a/pages/calonpelanggan/create.jsx b/pages/calonpelanggan/create.jsx index 4cffcab4f83f3afa0cfb2678154e5f4a4cf68ee2..e3b5f4e96b9adb67514b3c013ed94d1299beb655 100644 --- a/pages/calonpelanggan/create.jsx +++ b/pages/calonpelanggan/create.jsx @@ -4,8 +4,7 @@ import { toast } from "react-toastify" import { useRouter } from "next/router" const Create = () => { const router = useRouter() - const { kelasID, namaKelas } = router?.state || {}; - const { isDisabled, setIsDisabled} = useState(false) + const [isDisabled, setIsDisabled] = useState(false) const [nama, setNama] = useState("") const [kelasPelanggan, setKelasPelanggan] = useState("") const [umur, setUmur] = useState("") @@ -14,11 +13,12 @@ const Create = () => { const statusPelanggan = "Calon" useEffect(() => { - if (router?.location?.state?.kelasID) { - setKelasPelanggan(router.location.state.kelasID); + if (!router.isReady) return; + if (router.query.kelasID) { + setKelasPelanggan(router.query.kelasID); setIsDisabled(true); } - }, [router?.location?.state?.kelasID]); + }, [router.isReady, router.query.kelasID]) const handleUpdate = async () => { const body = JSON.stringify({ @@ -45,7 +45,23 @@ const Create = () => { return } toast.success("Successfully created!") - router.push("/calonpelanggan") + const token = window.localStorage.getItem("token") + if (!token) { + router.push("/") + return + } + const tokenParsed = token.split(" ")[1] + fetch(`https://rpl-backend-production.up.railway.app/v1/auth/verify/${tokenParsed}`).then(async (response) => { + const responsejson = await response.json(); + if (responsejson.data.tipe_user === "ADMIN") { + router.push("/calonpelanggan") + return + } + router.push("/") + }).catch(error => { + console.error(error) + return + }) return; } return <> @@ -58,8 +74,8 @@ const Create = () => { }}>Back</span> </div> <h1 className="text-[#F875AA] font-extrabold text-5xl mb-20 text-center">Form Pendaftaran Kursus Mengemudi RPL</h1> - <div className="text-[#F875AA] font-extrabold text-5xl mb-20 text-center">{kelasID && ( - <span> Kelas {namaKelas}</span>)} + <div className="text-[#F875AA] font-extrabold text-3xl mb-20 text-center">{router.query.kelasID && ( + <span> Kelas {router.query.namaKelas}</span>)} </div> <form className="w-2/3 mx-auto space-y-10 flex flex-col align-middle justify-evenly" onSubmit={(e) => { e.preventDefault() @@ -96,7 +112,7 @@ const Create = () => { setAlamat(e.target.value) }} type="text" required className="drop-shadow-xl w-2/3 p-2 rounded-xl" /> </div> - <input type="submit" className="bg-[#F875AA] px-8 py-3 text-xl font-bold text-white rounded-xl mx-auto" value={"Simpan"} /> + <input type="submit" className="bg-[#F875AA] px-8 py-3 text-xl font-bold text-white rounded-xl mx-auto hover:cursor-pointer" value={"Simpan"} /> </form> </main> diff --git a/pages/calonpelanggan/edit/[id].jsx b/pages/calonpelanggan/edit/[id].jsx index b68e8d3bd6abd1e8ad0795950d15d6d5bd27a31a..129f6df9ded401ecb1d376829fdf88b83d9c7928 100644 --- a/pages/calonpelanggan/edit/[id].jsx +++ b/pages/calonpelanggan/edit/[id].jsx @@ -50,6 +50,7 @@ const Edit = () => { } useEffect(() => { + if (!router.isReady) return; const token = window.localStorage.getItem("token") if (token === undefined || token === null) { window.location.replace("/auth/login") @@ -76,14 +77,14 @@ const Edit = () => { setAdminKursus(responsejson.data.adminKursus) }) //eslint-disable-next-line - }, []) + }, [router.isReady]) 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("/") + router.replace("/calonpelanggan") }}>Back</span> </div> <h1 className="text-[#F875AA] font-extrabold text-5xl mb-20 text-center">Update Pelanggan</h1> @@ -129,7 +130,8 @@ const Edit = () => { <div className="flex flex-row align-middle justify-between"> <span className="h-min my-auto font-bold text-lg">Status Pelanggan</span> <select value={statusPelanggan} onChange={(e) => { - setStatusPelanggan(e.target.value)}}> + setStatusPelanggan(e.target.value) + }}> <option value="Calon">Calon</option> <option value="Siswa">Siswa</option> <option value="Lulus">Lulus</option> </select> @@ -140,7 +142,7 @@ const Edit = () => { setAdminKursus(e.target.value) }} type="number" required className="drop-shadow-xl w-2/3 p-2 rounded-xl" /> </div> - <input type="submit" className="bg-[#F875AA] px-8 py-3 text-xl font-bold text-white rounded-xl mx-auto" value={"Simpan"} /> + <input type="submit" className="bg-[#F875AA] px-8 py-3 text-xl font-bold text-white rounded-xl mx-auto hover:cursor-pointer" value={"Simpan"} /> </form> </main> diff --git a/pages/calonpelanggan/index.jsx b/pages/calonpelanggan/index.jsx index b558b00fdaf966ed37f64530790a56e5e93dc2f1..baa80bd56b981eedc7ecca5fffc7a98948ff3647 100644 --- a/pages/calonpelanggan/index.jsx +++ b/pages/calonpelanggan/index.jsx @@ -85,7 +85,7 @@ const Index = () => { <div className="w-full mb-2"> <span className="text-[#F875AA] font-bold text-2xl hover:cursor-pointer" onClick={(e) => { e.preventDefault() - router.push("/dashboard/admin") + router.replace("/dashboard/admin") }}>Back</span> </div> <div className="flex flex-row align-middle justify-between"> diff --git a/pages/dashboard/admin.jsx b/pages/dashboard/admin.jsx index 87d9732320ad064c527fd6df4de12ba032146d73..839c194509e6470459279ec2707b2a5131ebf6d1 100644 --- a/pages/dashboard/admin.jsx +++ b/pages/dashboard/admin.jsx @@ -1,59 +1,53 @@ import Template from "@/components/templatenofooter" import { toast } from "react-toastify" -import { useEffect, useState} from "react" +import { useEffect, useState } from "react" import { useRouter } from "next/router" +import Image from "next/image" const DashboardAdmin = () => { - const router = useRouter(); - const [username, setUsername] = useState(null) - - useEffect(() => { - const token = window.localStorage.getItem("token") - if (!token){ + const router = useRouter(); + const [username, setUsername] = useState(null) + + useEffect(() => { + const token = window.localStorage.getItem("token") + if (!token) { + window.location.replace("/auth/login") + } + const tokenParsed = token.split(" ")[1] + fetch(`https://rpl-backend-production.up.railway.app/v1/auth/verify/${tokenParsed}`).then(async (response) => { + if (response.status !== 200) { + toast.error("Failed to retrieve items") + return; + } + const responsejson = await response.json(); + if (responsejson.data.tipe_user !== "ADMIN") { window.location.replace("/auth/login") + return } - const tokenParsed = token.split(" ")[1] - fetch(`https://rpl-backend-production.up.railway.app/v1/auth/verify/${tokenParsed}`).then(async (response) => { - if (response.status !== 200){ - toast.error("Failed to retrieve items") - return; - } - const responsejson = await response.json(); - if (responsejson.data.tipe_user !== "ADMIN"){ - window.location.replace("/auth/login") - return - } - setUsername(responsejson.data.username) + setUsername(responsejson.data.username) - }).catch(error=>{ - console.error(error) - return - }) - }, []) + }).catch(error => { + console.error(error) + return + }) + }, []) return ( <Template> - - <main className="min-h-screen px-14 py-10 bg-[#FFF6F6]"> - - <div></div> - <div className="text-[#F875AA] font-extrabold text-5xl mt-10 mb-20 text-center">Selamat datang kembali, {username}!</div> - <div className="w-[515px] h-[462px] absolute bg-white rounded-[15px] shadow left-1/2 transform -translate-x-1/2" /> - <div className="text-[#F875AA] w-[226px] h-[95px] absolute text-center text-[32px] font-extrabold left-1/2 transform -translate-x-1/2 mt-5">Data<br/>Pelanggan</div> - <div className="w-[126px] h-[53px] top-[680px] absolute left-1/2 transform -translate-x-1/2"> - <button onClick={(e) => { - e.preventDefault(); - router.push("/calonpelanggan") - return; - }} className="bg-[#AFDEFC] w-[126px] h-[53px] text-lg font-bold text-black rounded-2xl">Ubah</button> - </div> - <img className="w-[171px] h-[171px] absolute transform left-1/2 -translate-x-1/2 mt-40" src="/client.png" /> - </main> + <main className="min-h-screen p-28 flex flex-col align-middle justify-center bg-[#FFF6F6] space-y-20"> + <h1 className="text-5xl text-center font-extrabold text-[#F875AA]">Selamat datang kembali, {username}</h1> + <div className="bg-white rounded-xl p-10 space-y-14 flex flex-col align-middle justify-evenly shadow-xl shadow-[#FFDFE0] w-1/3 mx-auto"> + <span className="text-center font-bold text-4xl text-[#F875AA]">Data <br></br>Pelanggan</span> + <Image className="mx-auto" src="/client.png" width={126} height={53} alt="Data Kelas" /> + <button onClick={(e) => { + e.preventDefault(); + router.push("/calonpelanggan") + return; + }} className="bg-sky-200 rounded-xl font-bold text-center w-min mx-auto px-10 py-3">Ubah</button> + </div> + </main> </Template> - - ) - } export default DashboardAdmin \ No newline at end of file diff --git a/pages/dashboard/owner.jsx b/pages/dashboard/owner.jsx index 652182d19f1fcdd2ac4c175065a3c4661cf31bad..bd5cdf978d12488d2f1e84ab38e548e090851b67 100644 --- a/pages/dashboard/owner.jsx +++ b/pages/dashboard/owner.jsx @@ -1,92 +1,78 @@ import Template from "@/components/templatenofooter" import { toast } from "react-toastify" -import { useEffect} from "react" +import { useEffect } from "react" import { useRouter } from "next/router" +import Image from "next/image" const DashboardOwner = () => { - const router = useRouter(); + const router = useRouter(); - useEffect(() => { - const token = window.localStorage.getItem("token") - if (!token){ - window.location.replace("/auth/login") + useEffect(() => { + const token = window.localStorage.getItem("token") + if (!token) { + window.location.replace("/auth/login") + } + const tokenParsed = token.split(" ")[1] + fetch(`https://rpl-backend-production.up.railway.app/v1/auth/verify/${tokenParsed}`).then(async (response) => { + if (response.status !== 200) { + console.log(response) + toast.error("Failed to retrieve items") + return; } - const tokenParsed = token.split(" ")[1] - fetch(`https://rpl-backend-production.up.railway.app/v1/auth/verify/${tokenParsed}`).then(async (response) => { - if (response.status !== 200){ - console.log(response) - toast.error("Failed to retrieve items") - return; - } - const responsejson = await response.json(); - if (responsejson.data.tipe_user !== "OWNER"){ - window.location.replace("/auth/login") - return - } - }).catch(error=>{ - console.error(error) + const responsejson = await response.json(); + if (responsejson.data.tipe_user !== "OWNER") { + window.location.replace("/auth/login") return - }) - }, []) + } + }).catch(error => { + console.error(error) + return + }) + }, []) - return ( + return ( <Template> - <main className="min-h-screen px-14 py-7 bg-[#FFF6F6]"> - <div className="w-full mb-10"></div> - <div className="w-[690px] h-[59px] left-[462px] top-[200px] absolute text-[#F875AA] text-[40px] font-extrabold">Selamat datang kembali, Helmi!</div> - <div className="w-[317px] h-[271px] left-[168px] top-[341px] absolute bg-white rounded-[15px] shadow" /> - <img className="w-[99px] h-[100px] left-[277px] top-[427px] absolute" src="/todolist.png" /> - <div className="w-[207px] h-[34px] left-[223px] top-[351px] absolute text-center text-[#F875AA] text-xl font-extrabold font-">Data Kelas Yang Tersedia</div> - <div className="w-[126px] h-[53px] left-[263px] top-[544px] absolute"> - <div className="w-[126px] h-[53px] left-0 top-0 absolute bg-sky-200 rounded-[15px]" /> - <span className="w-[84.28px] h-[28.33px] left-[21px] top-[15px] absolute text-center text-black text-base font-bold font- hover:cursor-pointer" onClick={(e) => { - e.preventDefault() - router.push("/kelasmengemudi") - }}>Ubah</span> - </div> - <div className="w-[317px] h-[271px] left-[629px] top-[341px] absolute bg-white rounded-[15px] shadow" /> - <div className="w-[207px] h-[34px] left-[684px] top-[351px] absolute text-center text-[#F875AA] text-xl font-extrabold font-">Akun Pengguna Admin</div> - <img className="w-[117px] h-[117px] left-[732px] top-[419px] absolute" src="/setting.png" /> - <div className="w-[126px] h-[53px] left-[724px] top-[544px] absolute"> - <div className="w-[126px] h-[53px] left-0 top-0 absolute bg-sky-200 rounded-[15px]" /> - <span className="w-[84.28px] h-[28.33px] left-[21px] top-[15px] absolute text-center text-black text-base font-bold font- hover:cursor-pointer" onClick={(e) => { - e.preventDefault() - router.push("/adminkursus") - }}>Ubah</span> - </div> - <div className="w-[317px] h-[271px] left-[1090px] top-[345px] absolute bg-white rounded-[15px] shadow" /> - <div className="w-[207px] h-[57px] left-[1145px] top-[355px] absolute text-center text-[#F875AA] text-xl font-extrabold font-">Info Perusahaan dan FAQ</div> - <img className="w-[108px] h-[108px] left-[1195px] top-[428px] absolute" src="/briefcase.png" /> - <div className="w-[126px] h-[53px] left-[1185px] top-[548px] absolute"> - <div className="w-[126px] h-[53px] left-0 top-0 absolute bg-sky-200 rounded-[15px]" /> - <span className="w-[84.28px] h-[28.33px] left-[21px] top-[15px] absolute text-center text-black text-base font-bold font- hover:cursor-pointer" onClick={(e) => { - e.preventDefault() - router.push("/infoperusahaan") - }}>Ubah</span> - </div> - <div className="w-[317px] h-[271px] left-[418px] top-[694px] absolute bg-white rounded-[15px] shadow" /> - <div className="w-[207px] h-[34px] left-[473px] top-[704px] absolute text-center text-[#F875AA] text-xl font-extrabold font-">Data<br/> Kendaraan</div> - <img className="w-[138px] h-[138px] left-[508px] top-[759px] absolute" src="/sedan.png" /> - <div className="w-[126px] h-[53px] left-[513px] top-[897px] absolute"> - <div className="w-[126px] h-[53px] left-0 top-0 absolute bg-sky-200 rounded-[15px]" /> - <span className="w-[84.28px] h-[28.33px] left-[21px] top-[15px] absolute text-center text-black text-base font-bold font- hover:cursor-pointer" onClick={(e) => { - e.preventDefault() - router.push("/kendaraan") - }}>Ubah</span> + <main className="min-h-screen px-20 py-20 bg-[#FFF6F6] flex flex-col align-middle space-y-20"> + <h2 className="text-center text-5xl font-extrabold text-[#F875AA] ">Selamat datang kembali, Helmi!</h2> + <div className="flex flex-row align-middle justify-evenly"> + <div className="bg-white rounded-xl px-5 py-10 space-y-5 flex flex-col align-middle justify-evenly shadow-xl shadow-[#FFDFE0] w-1/4"> + <span className="text-center font-extrabold text-xl text-[#F875AA]">Data Kelas Yang Tersedia</span> + <Image className="mx-auto" src="/todolist.png" width={99} height={100} alt="Data Kelas" /> + <button className="bg-sky-200 rounded-xl font-bold text-center w-min mx-auto px-10 py-3" onClick={ + () => router.push("/kelasmengemudi")}>Ubah</button> + </div> + <div className="bg-white rounded-xl px-5 py-10 space-y-5 flex flex-col align-middle justify-evenly shadow-xl shadow-[#FFDFE0] w-1/4"> + <span className="text-center font-extrabold text-xl text-[#F875AA]">Akun Pengguna Admin</span> + <Image className="mx-auto" src="/setting.png" width={117} height={117} alt="Akun Pengguna Admin" /> + <button className="bg-sky-200 rounded-xl font-bold text-center w-min mx-auto px-10 py-3" onClick={ + () => router.push("/adminkursus")}>Ubah</button> + </div> + <div className="bg-white rounded-xl px-5 py-10 space-y-5 flex flex-col align-middle justify-evenly shadow-xl shadow-[#FFDFE0] w-1/4"> + <span className="text-center font-extrabold text-xl text-[#F875AA]">Info Perusahaan dan FAQ</span> + <Image className="mx-auto" src="/briefcase.png" width={108} height={108} alt="Data Kelas" /> + <button className="bg-sky-200 rounded-xl font-bold text-center w-min mx-auto px-10 py-3" onClick={ + () => router.push("/infoperusahaan")}>Ubah</button> + </div> + + </div> + <div className="flex flex-row align-middle justify-center space-x-32"> + <div className="bg-white rounded-xl px-5 py-10 space-y-5 flex flex-col align-middle justify-evenly shadow-xl shadow-[#FFDFE0] w-1/4"> + <span className="text-center font-extrabold text-xl text-[#F875AA]">Data Kendaraan</span> + <Image className="mx-auto" src="/sedan.png" width={117} height={117} alt="Data Kendaraan" /> + <button className="bg-sky-200 rounded-xl font-bold text-center w-min mx-auto px-10 py-3" onClick={ + () => router.push("/kendaraan")}>Ubah</button> + </div> + <div className="bg-white rounded-xl px-5 py-10 space-y-5 flex flex-col align-middle justify-evenly shadow-xl shadow-[#FFDFE0] w-1/4"> + <span className="text-center font-extrabold text-xl text-[#F875AA]">Data Instruktur</span> + <Image className="mx-auto" src="/instructor.png" width={112} height={112} alt="Data Instruktur" /> + <button className="bg-sky-200 rounded-xl font-bold text-center w-min mx-auto px-10 py-3" onClick={ + () => router.push("/instruktur")}>Ubah</button> + </div> + </div> - <div className="w-[317px] h-[271px] left-[876px] top-[692px] absolute bg-white rounded-[15px] shadow" /> - <div className="w-[207px] h-[34px] left-[931px] top-[702px] absolute text-center text-[#F875AA] text-xl font-extrabold font-">Data <br/>Instruktur</div> - <img className="w-28 h-28 left-[979px] top-[766px] absolute" src="/instructor.png" /> - <div className="w-[126px] h-[53px] left-[971px] top-[895px] absolute"> - <div className="w-[126px] h-[53px] left-0 top-0 absolute bg-sky-200 rounded-[15px]" /> - <span className="w-[84.28px] h-[28.33px] left-[21px] top-[15px] absolute text-center text-black text-base font-bold font- hover:cursor-pointer" onClick={(e) => { - e.preventDefault() - router.push("/instruktur") - }}>Ubah</span> - </div> </main> </Template> - + ) } export default DashboardOwner diff --git a/pages/index.jsx b/pages/index.jsx index 31586af6fc386c366158f7351c0623c9b6457949..5263a9385b37e17b20f3cd01ab064b59d79b15b1 100644 --- a/pages/index.jsx +++ b/pages/index.jsx @@ -5,6 +5,46 @@ import { useRouter } from "next/router" export default function Home({ kelasMengemudi, propertyWebsite }) { const router = useRouter(); + useEffect(() => { + const token = window.localStorage.getItem("token") + if (!token) { + window.location.replace("/auth/login") + } + const tokenParsed = token.split(" ")[1] + fetch(`https://rpl-backend-production.up.railway.app/v1/auth/verify/${tokenParsed}`).then(async (response) => { + if (response.status !== 200) { + toast.error("Failed to retrieve user") + return; + } + const responsejson = await response.json(); + if (responsejson.data.tipe_user !== "OWNER") { + window.location.replace("/auth/login") + return + } + }).catch(error => { + console.error(error) + return + }) + + fetch("https://rpl-backend-production.up.railway.app/v1/kelasmengemudi/list", { + method: "GET", + headers: { + Authorization: token + } + }).then(async (response) => { + if (response.status !== 200) { + toast.error("Failed to retrieve kelas") + return; + } + const responsejson = await response.json(); + setKelasMengemudi(responsejson.data) + + }).catch(error => { + console.error(error) + return + }) + }, []) + return <> <Template> <main className="min-h-screen px-14 py-5 bg-[#FFF6F6]"> @@ -21,25 +61,25 @@ export default function Home({ kelasMengemudi, propertyWebsite }) { <div className={`max-h-fit px-28 mt-10 mx-auto max-w-[1270px] relative grid grid-cols-3 gap-x-8 gap-y-8`}> {kelasMengemudi.map((row, index) => { return ( - <div key={row.kelasMengemudiID} - className={`relative col-span-1 row-span-1 col-start-${(index % 3) + 1} row-start-${Math.floor(index / 3) + 1}`}> - <div className="w-[320px] h-[360px] bg-white rounded-[15px] shadow relative flex flex-col justify-center items-center"> - <span className="text-[#F875AA] text-xl font-extrabold">{row.namaKelas}</span> - <span className="text-center text-black text-base mt-8">Harga: Rp{row.hargaKelas}</span> - <span className="text-center text-black text-base mt-3">Total Jam Kursus: {2*row.jumlahSesi}</span> - <span className="text-center text-black text-base mt-3">Jumlah Sesi: {row.jumlahSesi}</span> - <span className="text-center text-black text-base mt-3">Nama Kendaraan: {row.namaKendaraan}</span> - <span className="text-center text-black text-base mt-3">Jenis Kendaraan: {row.jenisKendaraan}</span> - - <button onClick={(e) => { - e.preventDefault(); - router.push({ - pathname: "/calonpelanggan/create", - query: {kelasID: row.kelasMengemudiID, namaKelas: row.namaKelas}, - }) - }} className="bg-[#AFDEFC] w-[126px] h-[53px] p-3 text-lg font-bold text-black rounded-2xl mt-8">Daftar</button> - </div> - </div>); + <div key={row.kelasMengemudiID} + className={`relative col-span-1 row-span-1 col-start-${(index % 3) + 1} row-start-${Math.floor(index / 3) + 1}`}> + <div className="w-[320px] h-[360px] bg-white rounded-[15px] shadow-xl shadow-[#FFDFE0] relative flex flex-col justify-center items-center"> + <span className="text-[#F875AA] text-xl font-extrabold">{row.namaKelas}</span> + <span className="text-center text-black text-base mt-8">Harga: Rp{row.hargaKelas}</span> + <span className="text-center text-black text-base mt-3">Total Jam Kursus: {2 * row.jumlahSesi}</span> + <span className="text-center text-black text-base mt-3">Jumlah Sesi: {row.jumlahSesi}</span> + <span className="text-center text-black text-base mt-3">Nama Kendaraan: {row.namaKendaraan}</span> + <span className="text-center text-black text-base mt-3">Jenis Kendaraan: {row.jenisKendaraan}</span> + + <button onClick={(e) => { + e.preventDefault(); + router.push({ + pathname: "/calonpelanggan/create", + query: { kelasID: row.kelasMengemudiID, namaKelas: row.namaKelas }, + }) + }} className="bg-[#AFDEFC] w-[126px] h-[53px] p-3 text-lg font-bold text-black rounded-2xl mt-8">Daftar</button> + </div> + </div>); })} </div> diff --git a/pages/instruktur/create.jsx b/pages/instruktur/create.jsx index b56d9ff435106fb8cea0c54823116436db54eb2d..e1f5020a5bd6d57c13fa73af639ef00b5a081a15 100644 --- a/pages/instruktur/create.jsx +++ b/pages/instruktur/create.jsx @@ -49,10 +49,10 @@ const Create = () => { <div className="w-full mb-2"> <span className="text-[#F875AA] font-bold text-2xl hover:cursor-pointer" onClick={(e) => { e.preventDefault() - router.push("/") + router.back() }}>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..90a0dfbda4104b71714796c2f3c3d5b00c16a4ab 100644 --- a/pages/instruktur/edit/[id].jsx +++ b/pages/instruktur/edit/[id].jsx @@ -74,10 +74,10 @@ const Edit = () => { <div className="w-full mb-2"> <span className="text-[#F875AA] font-bold text-2xl hover:cursor-pointer" onClick={(e) => { e.preventDefault() - router.push("/") + router.back("/") }}>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/instruktur/index.jsx b/pages/instruktur/index.jsx index 018cb35c3043970d6f358ab733800e8951214df1..87bd9a7a809e17e387083ecf85df6d718886d9a4 100644 --- a/pages/instruktur/index.jsx +++ b/pages/instruktur/index.jsx @@ -85,7 +85,7 @@ const Index = () => { <div className="w-full mb-2"> <span className="text-[#F875AA] font-bold text-2xl hover:cursor-pointer" onClick={(e) => { e.preventDefault() - router.push("/") + router.back() }}>Back</span> </div> <div className="flex flex-row align-middle justify-between"> diff --git a/pages/kendaraan/create.jsx b/pages/kendaraan/create.jsx new file mode 100644 index 0000000000000000000000000000000000000000..d9de0faa908643373f6220ae823d35e4b5972423 --- /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.back() + }}>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..cb0b570a59e5944e9dc2d2b8ad2deb7cbf96e81e --- /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.back() + }}>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..1bea2c3fde50decda869d28fba3e749e17357de9 --- /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.back() + }}>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