package handlers import ( "log" "net/http" "strconv" "whatsapp-bot/db" "whatsapp-bot/services" "github.com/gin-gonic/gin" ) func ShowDashboard(c *gin.Context) { // 1. Fetch Appointments for the Table type Appt struct { ID int CustomerPhone string Date string Status string } var appts []Appt approws, err := db.Conn.Query("SELECT id, customer_phone, appointment_date, status FROM appointments ORDER BY id DESC") if err != nil { log.Println("Appt Query Error:", err) } else { defer approws.Close() for approws.Next() { var a Appt approws.Scan(&a.ID, &a.CustomerPhone, &a.Date, &a.Status) appts = append(appts, a) } } // 2. Fetch Chats for the Sidebar type Chat struct { ID int Title string } var chats []Chat chatrows, err := db.Conn.Query("SELECT id FROM chats ORDER BY id DESC") if err != nil { log.Println("Chat Query Error:", err) } else { defer chatrows.Close() for chatrows.Next() { var ch Chat chatrows.Scan(&ch.ID) // Give it a default title so the sidebar isn't empty ch.Title = "Chat #" + strconv.Itoa(ch.ID) chats = append(chats, ch) } } // 3. Render the Template with BOTH data sets c.HTML(http.StatusOK, "dashboard.html", gin.H{ "Appointments": appts, "Chats": chats, }) } // Test OpenRouter via the Dashboard func TestAIHandler(c *gin.Context) { var body struct { Prompt string `json:"prompt"` } if err := c.BindJSON(&body); err != nil { c.JSON(400, gin.H{"response": "Invalid request, dummy."}) return } // Calling the service we wrote earlier response, err := services.GetAIResponse([]services.Message{ {Role: "user", Content: body.Prompt}, }) if err != nil { c.JSON(500, gin.H{"response": "AI Error: " + err.Error()}) return } c.JSON(200, gin.H{"response": response}) } // Add this to handlers/dashboard.go func CreateAppointmentHandler(c *gin.Context) { var body struct { Phone string `json:"phone"` Date string `json:"date"` } if err := c.BindJSON(&body); err != nil { c.Status(400) return } // Use the helper function instead of raw SQL here if err := db.SaveAppointment(body.Phone, body.Date); err != nil { c.JSON(500, gin.H{"error": err.Error()}) return } c.Status(200) } // Manage/Delete Appointment func DeleteAppointmentHandler(c *gin.Context) { id := c.Param("id") _, err := db.Conn.Exec("DELETE FROM appointments WHERE id = ?", id) if err != nil { c.Status(http.StatusInternalServerError) return } c.Status(http.StatusOK) } // PUT /admin/appointment/:id func UpdateAppointmentHandler(c *gin.Context) { id := c.Param("id") var body struct { Phone string `json:"phone"` Date string `json:"date"` } if err := c.BindJSON(&body); err != nil { c.Status(400) return } _, err := db.Conn.Exec( "UPDATE appointments SET customer_phone = ?, appointment_date = ? WHERE id = ?", body.Phone, body.Date, id, ) if err != nil { c.JSON(500, gin.H{"error": err.Error()}) return } c.Status(200) } // POST /admin/chat func NewChatHandler(c *gin.Context) { // Insert a new chat record. In SQLite, this is enough to generate an ID. res, err := db.Conn.Exec("INSERT INTO chats (title) VALUES ('New Chat')") if err != nil { log.Println("Database Error in NewChat:", err) c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create chat"}) return } id, _ := res.LastInsertId() c.JSON(http.StatusOK, gin.H{"id": id}) } // GET /admin/chat/:id/messages func GetMessagesHandler(c *gin.Context) { id := c.Param("id") rows, _ := db.Conn.Query("SELECT role, content FROM messages WHERE chat_id = ? ORDER BY created_at ASC", id) defer rows.Close() var msgs []services.Message for rows.Next() { var m services.Message rows.Scan(&m.Role, &m.Content) msgs = append(msgs, m) } c.JSON(200, msgs) } // POST /admin/chat/:id/message func PostMessageHandler(c *gin.Context) { chatId := c.Param("id") var body struct { Content string `json:"content"` } c.BindJSON(&body) // 1. Save User Message db.Conn.Exec("INSERT INTO messages (chat_id, role, content) VALUES (?, 'user', ?)", chatId, body.Content) // 2. Fetch history for AI rows, _ := db.Conn.Query("SELECT role, content FROM messages WHERE chat_id = ? ORDER BY created_at ASC", chatId) var history []services.Message for rows.Next() { var m services.Message rows.Scan(&m.Role, &m.Content) history = append(history, m) } // 3. Get AI Response aiResp, _ := services.GetAIResponse(history) // 4. Save Assistant Message db.Conn.Exec("INSERT INTO messages (chat_id, role, content) VALUES (?, 'assistant', ?)", chatId, aiResp) c.JSON(200, gin.H{"response": aiResp}) }