update 18 mei
This commit is contained in:
parent
8d35ec81d8
commit
0aed7a7c01
@ -53,6 +53,7 @@ func main() {
|
|||||||
protected.POST("/bookings", controllers.CreateBooking)
|
protected.POST("/bookings", controllers.CreateBooking)
|
||||||
protected.GET("/bookings", controllers.GetAllBookings)
|
protected.GET("/bookings", controllers.GetAllBookings)
|
||||||
protected.PUT("/bookings/:id/status", controllers.UpdateBookingStatus)
|
protected.PUT("/bookings/:id/status", controllers.UpdateBookingStatus)
|
||||||
|
protected.GET("/my-bookings", controllers.GetMyBookings)
|
||||||
|
|
||||||
// Admin (Manage Rooms)
|
// Admin (Manage Rooms)
|
||||||
protected.PUT("/admin/rooms/:id/status", controllers.UpdateRoomStatus)
|
protected.PUT("/admin/rooms/:id/status", controllers.UpdateRoomStatus)
|
||||||
|
|||||||
@ -26,7 +26,7 @@ func CreateBooking(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//Handle UUID
|
// Handle UUID User
|
||||||
userIDInterface, exists := c.Get("user_id")
|
userIDInterface, exists := c.Get("user_id")
|
||||||
if !exists {
|
if !exists {
|
||||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "User ID tidak ditemukan"})
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "User ID tidak ditemukan"})
|
||||||
@ -45,15 +45,18 @@ func CreateBooking(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 🌟 PERBAIKAN 1: Ambil Role User dari Token
|
||||||
|
userRoleInterface, _ := c.Get("role")
|
||||||
|
userRole, _ := userRoleInterface.(string)
|
||||||
|
|
||||||
// Validasi Waktu
|
// Validasi Waktu
|
||||||
if input.EndTime.Before(input.StartTime) {
|
if input.EndTime.Before(input.StartTime) {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Waktu selesai tidak boleh lebih awal dari waktu mulai!"})
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Waktu selesai tidak boleh lebih awal dari waktu mulai!"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// (Overlap Check)
|
// Overlap Check (Mencegah bentrok jadwal)
|
||||||
var count int64
|
var count int64
|
||||||
// KITA UBAH STATUSNYA MENJADI: status IN ('Pending', 'Approved')
|
|
||||||
config.DB.Model(&models.Booking{}).Where(
|
config.DB.Model(&models.Booking{}).Where(
|
||||||
"room_id = ? AND status IN ('Pending', 'Approved') AND ((start_time < ? AND end_time > ?) OR (start_time < ? AND end_time > ?) OR (start_time >= ? AND end_time <= ?))",
|
"room_id = ? AND status IN ('Pending', 'Approved') AND ((start_time < ? AND end_time > ?) OR (start_time < ? AND end_time > ?) OR (start_time >= ? AND end_time <= ?))",
|
||||||
input.RoomID, input.EndTime, input.StartTime, input.EndTime, input.StartTime, input.StartTime, input.EndTime,
|
input.RoomID, input.EndTime, input.StartTime, input.EndTime, input.StartTime, input.StartTime, input.EndTime,
|
||||||
@ -64,6 +67,12 @@ func CreateBooking(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 🌟 PERBAIKAN 1 Lanjutan: Penentuan Status Otomatis
|
||||||
|
statusPeminjaman := "Pending" // Default untuk student
|
||||||
|
if userRole == "lecturer" {
|
||||||
|
statusPeminjaman = "Approved" // Dosen otomatis disetujui!
|
||||||
|
}
|
||||||
|
|
||||||
// Simpan Booking
|
// Simpan Booking
|
||||||
booking := models.Booking{
|
booking := models.Booking{
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
@ -71,7 +80,7 @@ func CreateBooking(c *gin.Context) {
|
|||||||
StartTime: input.StartTime,
|
StartTime: input.StartTime,
|
||||||
EndTime: input.EndTime,
|
EndTime: input.EndTime,
|
||||||
Purpose: input.Purpose,
|
Purpose: input.Purpose,
|
||||||
Status: "Pending",
|
Status: statusPeminjaman, // <-- Gunakan variabel statusPeminjaman
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := config.DB.Create(&booking).Error; err != nil {
|
if err := config.DB.Create(&booking).Error; err != nil {
|
||||||
@ -86,18 +95,21 @@ func CreateBooking(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetUserBookings(c *gin.Context) {
|
// 🌟 PERBAIKAN 3: Fungsi khusus untuk mengambil riwayat pribadi
|
||||||
|
func GetMyBookings(c *gin.Context) {
|
||||||
var bookings []models.Booking
|
var bookings []models.Booking
|
||||||
|
|
||||||
userID, _ := c.Get("user_id")
|
userID, _ := c.Get("user_id")
|
||||||
role, _ := c.Get("role")
|
role, _ := c.Get("role")
|
||||||
|
|
||||||
if role == "admin" {
|
if role == "admin" {
|
||||||
|
// Admin bisa melihat semua riwayat
|
||||||
if err := config.DB.Preload("Room").Preload("User").Order("created_at desc").Find(&bookings).Error; err != nil {
|
if err := config.DB.Preload("Room").Preload("User").Order("created_at desc").Find(&bookings).Error; err != nil {
|
||||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Mahasiswa/Dosen HANYA BISA melihat riwayat miliknya sendiri
|
||||||
if err := config.DB.Preload("Room").Where("user_id = ?", userID).Order("created_at desc").Find(&bookings).Error; err != nil {
|
if err := config.DB.Preload("Room").Where("user_id = ?", userID).Order("created_at desc").Find(&bookings).Error; err != nil {
|
||||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
return
|
return
|
||||||
@ -122,13 +134,11 @@ func UpdateBookingStatus(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var booking models.Booking
|
var booking models.Booking
|
||||||
// KUNCI PERBAIKAN: Gunakan Where("booking_id = ?") agar tepat sasaran
|
|
||||||
if err := config.DB.Where("booking_id = ?", bookingID).First(&booking).Error; err != nil {
|
if err := config.DB.Where("booking_id = ?", bookingID).First(&booking).Error; err != nil {
|
||||||
c.JSON(http.StatusNotFound, gin.H{"error": "Data booking tidak ditemukan di database"})
|
c.JSON(http.StatusNotFound, gin.H{"error": "Data booking tidak ditemukan di database"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gunakan Switch Case (Clean Code) yang sudah kita bahas sebelumnya
|
|
||||||
switch input.Status {
|
switch input.Status {
|
||||||
case "Approved":
|
case "Approved":
|
||||||
if booking.RedeemCode == "" {
|
if booking.RedeemCode == "" {
|
||||||
@ -140,22 +150,10 @@ func UpdateBookingStatus(c *gin.Context) {
|
|||||||
|
|
||||||
booking.Status = input.Status
|
booking.Status = input.Status
|
||||||
|
|
||||||
|
// 🌟 PERBAIKAN 2: Menghapus blok Save dan JSON ganda yang bikin error
|
||||||
if err := config.DB.Save(&booking).Error; err != nil {
|
if err := config.DB.Save(&booking).Error; err != nil {
|
||||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Gagal menyimpan ke database"})
|
fmt.Println("🔥 ERROR DARI DATABASE:", err.Error())
|
||||||
return
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
}
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{
|
|
||||||
"message": "Status booking berhasil diperbarui!",
|
|
||||||
"data": booking,
|
|
||||||
})
|
|
||||||
|
|
||||||
booking.Status = input.Status
|
|
||||||
|
|
||||||
// KITA BUKA KEDOK ERROR DARI POSTGRESQL:
|
|
||||||
if err := config.DB.Save(&booking).Error; err != nil {
|
|
||||||
fmt.Println("🔥 ERROR DARI DATABASE:", err.Error()) // Cetak teks merah di terminal
|
|
||||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) // Tembak ke pop-up web
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,7 +163,7 @@ func UpdateBookingStatus(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// INPUT UNTUK ESP3
|
// INPUT UNTUK ESP32
|
||||||
type RedeemInput struct {
|
type RedeemInput struct {
|
||||||
RedeemCode string `json:"redeem_code" binding:"required"`
|
RedeemCode string `json:"redeem_code" binding:"required"`
|
||||||
}
|
}
|
||||||
@ -201,13 +199,11 @@ func VerifyRedeemCode(c *gin.Context) {
|
|||||||
func GetAllBookings(c *gin.Context) {
|
func GetAllBookings(c *gin.Context) {
|
||||||
var bookings []models.Booking
|
var bookings []models.Booking
|
||||||
|
|
||||||
// Preload digunakan untuk mengambil data Relasi (Nama Ruangan & Nama Peminjam)
|
|
||||||
if err := config.DB.Preload("Room").Preload("User").Order("created_at desc").Find(&bookings).Error; err != nil {
|
if err := config.DB.Preload("Room").Preload("User").Order("created_at desc").Find(&bookings).Error; err != nil {
|
||||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perhatikan: responsenya menggunakan "data: bookings" agar cocok dengan Frontend React-mu
|
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"status": "success",
|
"status": "success",
|
||||||
"data": bookings,
|
"data": bookings,
|
||||||
|
|||||||
@ -35,7 +35,8 @@ export default function HistoryPage() {
|
|||||||
|
|
||||||
const fetchHistory = async (token: string) => {
|
const fetchHistory = async (token: string) => {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get("http://localhost:8080/api/bookings", {
|
// PERBAIKAN: Ubah /api/bookings menjadi /api/my-bookings
|
||||||
|
const response = await axios.get("http://localhost:8080/api/my-bookings", {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
});
|
});
|
||||||
setBookings(response.data.data || []);
|
setBookings(response.data.data || []);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user