Files
feedmee/backend/handlers/api_admin.go

233 lines
5.9 KiB
Go

package handlers
import (
"encoding/json"
"net/http"
"github.com/go-chi/chi/v5"
)
func (app *App) HandleAdminMenu(w http.ResponseWriter, r *http.Request) {
var in struct {
Action string `json:"action"`
ID int `json:"id"`
Name string `json:"name"`
Category string `json:"category"`
}
if err := json.NewDecoder(r.Body).Decode(&in); err != nil {
http.Error(w, "invalid request", http.StatusBadRequest)
return
}
switch in.Action {
case "add":
_, err := app.DB.Exec("INSERT INTO menu_items (category, name) VALUES (?, ?)", in.Category, in.Name)
if err != nil {
http.Error(w, err.Error(), 500)
return
}
case "update":
_, err := app.DB.Exec("UPDATE menu_items SET name = ? WHERE id = ?", in.Name, in.ID)
if err != nil {
http.Error(w, err.Error(), 500)
return
}
case "delete":
_, err := app.DB.Exec("DELETE FROM menu_items WHERE id = ?", in.ID)
if err != nil {
http.Error(w, err.Error(), 500)
return
}
}
// return updated menu
rows, _ := app.DB.Query("SELECT id, category, name FROM menu_items ORDER BY id ASC")
defer rows.Close()
var items []map[string]any
for rows.Next() {
var id int
var category, name string
rows.Scan(&id, &category, &name)
items = append(items, map[string]any{"id": id, "category": category, "name": name})
}
writeJSON(w, items)
}
func (app *App) HandleAdminUpdateOrderStatus(w http.ResponseWriter, r *http.Request) {
id := chi.URLParam(r, "id")
var in struct {
Status string `json:"status"`
}
if err := json.NewDecoder(r.Body).Decode(&in); err != nil {
http.Error(w, "invalid request", http.StatusBadRequest)
return
}
_, err := app.DB.Exec("UPDATE orders SET status = ? WHERE id = ?", in.Status, id)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
switch in.Status {
case "history":
// If status is history -> send deleted event
msg := map[string]any{"id": id, "status": "history", "event": "deleted"}
if data, err := json.Marshal(msg); err == nil {
app.Broker.broadcast <- data
}
case "active":
// If status is active -> send new order
var o Order
row := app.DB.QueryRow("SELECT id, username, soup, main, side, created_at, status FROM orders WHERE id = ?", id)
if err := row.Scan(&o.ID, &o.Username, &o.Soup, &o.Main, &o.Side, &o.CreatedAt, &o.Status); err == nil {
if data, err := json.Marshal(o); err == nil {
app.Broker.broadcast <- data
}
}
}
writeJSON(w, map[string]string{"status": "ok"})
}
func (app *App) HandleAdminDeleteOrder(w http.ResponseWriter, r *http.Request) {
id := chi.URLParam(r, "id")
// Step 1: set to history (so user views update immediately)
_, _ = app.DB.Exec("UPDATE orders SET status = 'history' WHERE id = ?", id)
// Step 2: broadcast history update
msg := map[string]any{"id": id, "status": "history", "event": "deleted"}
if data, err := json.Marshal(msg); err == nil {
app.Broker.broadcast <- data
}
// Step 3: hard delete from DB
_, err := app.DB.Exec("DELETE FROM orders WHERE id = ?", id)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
writeJSON(w, map[string]string{"status": "deleted"})
}
func (app *App) HandleGetUsers(w http.ResponseWriter, r *http.Request) {
rows, err := app.DB.Query("SELECT id, username, role FROM users ORDER BY id")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer rows.Close()
var users []map[string]any
for rows.Next() {
var id, role int
var username string
rows.Scan(&id, &username, &role)
users = append(users, map[string]any{"id": id, "username": username, "role": role})
}
writeJSON(w, users)
}
func (app *App) HandleUpdateUser(w http.ResponseWriter, r *http.Request) {
id := chi.URLParam(r, "id")
var req struct {
Username string `json:"username"`
Password string `json:"password"`
Role *int `json:"role"` // pointer = optional
}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "invalid request", http.StatusBadRequest)
return
}
if req.Username == "" && req.Password == "" && req.Role == nil {
http.Error(w, "nothing to update", http.StatusBadRequest)
return
}
// build dynamic UPDATE
query := "UPDATE users SET "
args := []any{}
first := true
if req.Username != "" {
if !first {
query += ", "
}
first = false
query += "username = ?"
args = append(args, req.Username)
}
if req.Password != "" {
if !first {
query += ", "
}
first = false
query += "password = ?"
args = append(args, req.Password)
}
if req.Role != nil {
if !first {
query += ", "
}
first = false
query += "role = ?"
args = append(args, *req.Role)
}
query += " WHERE id = ?"
args = append(args, id)
res, err := app.DB.Exec(query, args...)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if n, _ := res.RowsAffected(); n == 0 {
http.Error(w, "user not found", http.StatusNotFound)
return
}
writeJSON(w, map[string]string{"status": "updated"})
}
func (app *App) HandleDeleteUser(w http.ResponseWriter, r *http.Request) {
id := chi.URLParam(r, "id")
res, err := app.DB.Exec("DELETE FROM users WHERE id = ?", id)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
n, _ := res.RowsAffected()
if n == 0 {
http.Error(w, "user not found", http.StatusNotFound)
return
}
writeJSON(w, map[string]string{"status": "deleted"})
}
func (app *App) HandleGetAllOrders(w http.ResponseWriter, r *http.Request) {
rows, err := app.DB.Query("SELECT id, username, soup, main, side, created_at, status FROM orders ORDER BY id DESC")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer rows.Close()
var out []Order
for rows.Next() {
var o Order
if err := rows.Scan(&o.ID, &o.Username, &o.Soup, &o.Main, &o.Side, &o.CreatedAt, &o.Status); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
out = append(out, o)
}
writeJSON(w, out)
}