189 lines
6.7 KiB
TypeScript
189 lines
6.7 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import { useRouter } from "next/navigation";
|
|
|
|
export default function BookingPage() {
|
|
const router = useRouter();
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
|
|
// State untuk form input
|
|
const [formData, setFormData] = useState({
|
|
room: "Ruang T-301",
|
|
date: "",
|
|
startTime: "",
|
|
endTime: "",
|
|
purpose: "",
|
|
});
|
|
|
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) => {
|
|
setFormData({ ...formData, [e.target.name]: e.target.value });
|
|
};
|
|
|
|
// --- LOGIKA VALIDASI KHUSUS ---
|
|
const validateBookingRules = () => {
|
|
// 1. Pastikan tanggal dan jam sudah diisi
|
|
if (!formData.date || !formData.startTime) {
|
|
alert("Mohon lengkapi Tanggal dan Jam Mulai terlebih dahulu.");
|
|
return false;
|
|
}
|
|
|
|
// 2. Ambil Jam dari input (Format "HH:mm", kita ambil HH nya saja)
|
|
const startHour = parseInt(formData.startTime.split(":")[0]);
|
|
|
|
// 3. Cek apakah jam termasuk "Jam Khusus" (Diatas 21:00 ATAU Sebelum 06:00)
|
|
// Note: startHour >= 21 artinya jam 21:00 ke atas. startHour < 6 artinya jam 00:00 - 05:59
|
|
const isSpecialTime = startHour >= 21 || startHour < 6;
|
|
|
|
if (isSpecialTime) {
|
|
// Hitung selisih hari antara HARI INI dan TANGGAL BOOKING
|
|
const bookingDate = new Date(formData.date);
|
|
const today = new Date();
|
|
|
|
// Reset jam ke 00:00:00 agar perhitungan murni berdasarkan tanggal
|
|
bookingDate.setHours(0, 0, 0, 0);
|
|
today.setHours(0, 0, 0, 0);
|
|
|
|
// Hitung selisih waktu dalam milidetik
|
|
const diffTime = bookingDate.getTime() - today.getTime();
|
|
// Konversi milidetik ke hari (1 hari = 1000ms * 3600detik * 24jam)
|
|
const diffDays = diffTime / (1000 * 3600 * 24);
|
|
|
|
// ATURAN: Jika selisih kurang dari 3 hari, tolak!
|
|
if (diffDays < 3) {
|
|
alert(
|
|
`Gagal! Peminjaman di jam khusus (${formData.startTime}) harus dilakukan minimal 3 hari sebelumnya.\n\n` +
|
|
`Jarak peminjaman Anda: ${diffDays} hari dari sekarang.`
|
|
);
|
|
return false; // Validasi Gagal
|
|
}
|
|
}
|
|
|
|
return true; // Validasi Berhasil
|
|
};
|
|
|
|
const handleSubmit = (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
|
|
// Jalankan validasi sebelum proses loading
|
|
const isValid = validateBookingRules();
|
|
if (!isValid) {
|
|
return; // Berhenti di sini jika validasi gagal
|
|
}
|
|
|
|
setIsLoading(true);
|
|
|
|
// --- LOGIKA SEMENTARA (MOCK) ---
|
|
console.log("Data Booking dikirim:", formData);
|
|
|
|
setTimeout(() => {
|
|
alert("Peminjaman Berhasil! Token akses Anda telah dibuat.");
|
|
setIsLoading(false);
|
|
router.push("/dashboard");
|
|
}, 1500);
|
|
};
|
|
|
|
return (
|
|
<div className="min-h-screen bg-gray-50 p-6 flex items-center justify-center">
|
|
<div className="w-full max-w-lg bg-white rounded-xl shadow-md border border-gray-200 overflow-hidden">
|
|
|
|
{/* Header Form */}
|
|
<div className="bg-yellow-500 px-6 py-4 flex justify-between items-center">
|
|
<h1 className="text-xl font-bold text-white">Formulir Peminjaman Ruang</h1>
|
|
<button
|
|
onClick={() => router.back()}
|
|
className="text-white/80 hover:text-white text-sm"
|
|
>
|
|
← Batal
|
|
</button>
|
|
</div>
|
|
|
|
<form onSubmit={handleSubmit} className="p-8 space-y-6">
|
|
|
|
{/* Pilihan Ruangan */}
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">Pilih Ruangan</label>
|
|
<select
|
|
name="room"
|
|
value={formData.room}
|
|
onChange={handleChange}
|
|
className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-yellow-400 outline-none text-gray-900"
|
|
>
|
|
<option value="Ruang T-301">Ruang T-301 (Teori)</option>
|
|
<option value="Ruang T-302">Ruang T-302 (Teori)</option>
|
|
<option value="Lab Kendali">Lab Sistem Kendali</option>
|
|
<option value="Lab IoT">Lab IoT & Embedded</option>
|
|
</select>
|
|
</div>
|
|
|
|
{/* Tanggal */}
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">Tanggal Peminjaman</label>
|
|
<input
|
|
type="date"
|
|
name="date"
|
|
required
|
|
value={formData.date}
|
|
onChange={handleChange}
|
|
className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-yellow-400 outline-none text-gray-900"
|
|
/>
|
|
</div>
|
|
|
|
{/* Waktu Mulai & Selesai */}
|
|
<div className="grid grid-cols-2 gap-4">
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">Waktu Mulai</label>
|
|
<input
|
|
type="time"
|
|
name="startTime"
|
|
required
|
|
value={formData.startTime}
|
|
onChange={handleChange}
|
|
className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-yellow-400 outline-none text-gray-900"
|
|
/>
|
|
<p className="text-xs text-gray-400 mt-1">*Jam 21:00-06:00 butuh H-3</p>
|
|
</div>
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">Waktu Selesai</label>
|
|
<input
|
|
type="time"
|
|
name="endTime"
|
|
required
|
|
value={formData.endTime}
|
|
onChange={handleChange}
|
|
className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-yellow-400 outline-none text-gray-900"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Keperluan */}
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">Keperluan</label>
|
|
<textarea
|
|
name="purpose"
|
|
rows={3}
|
|
placeholder="Contoh: Kuliah Pengganti Sistem Kendali Digital"
|
|
value={formData.purpose}
|
|
onChange={handleChange}
|
|
className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-yellow-400 outline-none text-gray-900"
|
|
></textarea>
|
|
</div>
|
|
|
|
{/* Tombol Submit */}
|
|
<button
|
|
type="submit"
|
|
disabled={isLoading}
|
|
className={`w-full py-3 rounded-lg text-white font-bold shadow transition-all
|
|
${isLoading
|
|
? "bg-gray-400 cursor-not-allowed"
|
|
: "bg-blue-600 hover:bg-blue-700 active:scale-95"
|
|
}`}
|
|
>
|
|
{isLoading ? "Memproses Jadwal..." : "Ajukan Peminjaman"}
|
|
</button>
|
|
|
|
</form>
|
|
</div>
|
|
</div>
|
|
);
|
|
} |