233 lines
5.9 KiB
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)
|
|
}
|