Refactored project structure
This commit is contained in:
232
backend/handlers/api_admin.go
Normal file
232
backend/handlers/api_admin.go
Normal file
@@ -0,0 +1,232 @@
|
||||
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)
|
||||
}
|
||||
Reference in New Issue
Block a user