package handlers import ( "database/sql" "net/http" "strconv" ) func (a *App) Admin(w http.ResponseWriter, r *http.Request) { data := map[string]any{} data["Departments"] = a.departments() data["Items"] = a.items() data["Settings"] = a.settings() data["Statuses"] = a.statuses() data["WorkflowRules"] = a.workflowRules() data["QuestTemplates"] = a.questTemplates() a.T.ExecuteTemplate(w, "admin.html", data) } func (a *App) AdminDepartment(w http.ResponseWriter, r *http.Request) { r.ParseForm() action := r.FormValue("action") id, _ := strconv.Atoi(r.FormValue("id")) name := r.FormValue("name") switch action { case "delete": a.DB.Exec(`delete from departments where id=?`, id) default: if id > 0 { a.DB.Exec(`update departments set name=? where id=?`, name, id) } else if name != "" { a.DB.Exec(`insert ignore into departments(name) values(?)`, name) } } http.Redirect(w, r, "/admin", 303) } func (a *App) AdminItem(w http.ResponseWriter, r *http.Request) { r.ParseForm() action := r.FormValue("action") id, _ := strconv.Atoi(r.FormValue("id")) sku, name, category := r.FormValue("sku"), r.FormValue("name"), r.FormValue("category") if category == "" { category = "item" } switch action { case "delete": a.DB.Exec(`delete from items where id=?`, id) default: if id > 0 { a.DB.Exec(`update items set sku=?, name=?, category=? where id=?`, sku, name, category, id) } else if sku != "" && name != "" { a.DB.Exec(`insert into items(sku,name,category) values(?,?,?)`, sku, name, category) } } http.Redirect(w, r, "/admin", 303) } func (a *App) AdminSetting(w http.ResponseWriter, r *http.Request) { r.ParseForm() key, value, desc := r.FormValue("setting_key"), r.FormValue("setting_value"), r.FormValue("description") if key != "" { a.DB.Exec(`insert into app_settings(setting_key,setting_value,description) values(?,?,?) on duplicate key update setting_value=values(setting_value), description=values(description)`, key, value, desc) } http.Redirect(w, r, "/admin", 303) } func (a *App) AdminStatus(w http.ResponseWriter, r *http.Request) { r.ParseForm() action := r.FormValue("action") id, _ := strconv.Atoi(r.FormValue("id")) scope, value, label := r.FormValue("scope"), r.FormValue("value"), r.FormValue("label") sortOrder, _ := strconv.Atoi(r.FormValue("sort_order")) terminal := r.FormValue("is_terminal") == "on" switch action { case "delete": a.DB.Exec(`delete from status_options where id=?`, id) default: if id > 0 { a.DB.Exec(`update status_options set scope=?, value=?, label=?, sort_order=?, is_terminal=? where id=?`, scope, value, label, sortOrder, terminal, id) } else if scope != "" && value != "" { a.DB.Exec(`insert into status_options(scope,value,label,sort_order,is_terminal) values(?,?,?,?,?)`, scope, value, label, sortOrder, terminal) } } http.Redirect(w, r, "/admin", 303) } func (a *App) AdminWorkflowRule(w http.ResponseWriter, r *http.Request) { r.ParseForm() action := r.FormValue("action") id, _ := strconv.Atoi(r.FormValue("id")) name, trigger, cond, actions := r.FormValue("name"), r.FormValue("trigger_name"), r.FormValue("condition_json"), r.FormValue("actions_json") enabled := r.FormValue("enabled") == "on" if cond == "" { cond = "{}" } if actions == "" { actions = "[]" } switch action { case "delete": a.DB.Exec(`delete from workflow_rules where id=?`, id) default: if id > 0 { a.DB.Exec(`update workflow_rules set name=?, trigger_name=?, condition_json=?, actions_json=?, enabled=? where id=?`, name, trigger, cond, actions, enabled, id) } else if name != "" { a.DB.Exec(`insert into workflow_rules(name,trigger_name,condition_json,actions_json,enabled) values(?,?,?,?,?)`, name, trigger, cond, actions, enabled) } } http.Redirect(w, r, "/admin", 303) } func (a *App) AdminQuestTemplate(w http.ResponseWriter, r *http.Request) { r.ParseForm() action := r.FormValue("action") id, _ := strconv.Atoi(r.FormValue("id")) deptID, _ := strconv.Atoi(r.FormValue("department_id")) sortOrder, _ := strconv.Atoi(r.FormValue("sort_order")) reward, _ := strconv.ParseFloat(r.FormValue("reward_percent"), 64) typ, title := r.FormValue("type"), r.FormValue("title_template") enabled := r.FormValue("enabled") == "on" dept := sql.NullInt64{Int64: int64(deptID), Valid: deptID > 0} switch action { case "delete": a.DB.Exec(`delete from quest_templates where id=?`, id) default: if id > 0 { a.DB.Exec(`update quest_templates set type=?, title_template=?, department_id=?, reward_percent=?, enabled=?, sort_order=? where id=?`, typ, title, dept, reward, enabled, sortOrder, id) } else if typ != "" && title != "" { a.DB.Exec(`insert into quest_templates(type,title_template,department_id,reward_percent,enabled,sort_order) values(?,?,?,?,?,?)`, typ, title, dept, reward, enabled, sortOrder) } } http.Redirect(w, r, "/admin", 303) } func (a *App) departments() []Row { rows, _ := a.DB.Query(`select id,name from departments order by name`) defer rows.Close() var out []Row for rows.Next() { var id int var name string rows.Scan(&id, &name) out = append(out, Row{"ID": id, "Name": name}) } return out } func (a *App) items() []Row { rows, _ := a.DB.Query(`select id,sku,name,category from items order by name`) defer rows.Close() var out []Row for rows.Next() { var id int var sku, name, cat string rows.Scan(&id, &sku, &name, &cat) out = append(out, Row{"ID": id, "SKU": sku, "Name": name, "Category": cat}) } return out } func (a *App) settings() []Row { rows, _ := a.DB.Query(`select setting_key,setting_value,description from app_settings order by setting_key`) defer rows.Close() var out []Row for rows.Next() { var k, v, d string rows.Scan(&k, &v, &d) out = append(out, Row{"Key": k, "Value": v, "Description": d}) } return out } func (a *App) statuses() []Row { rows, _ := a.DB.Query(`select id,scope,value,label,sort_order,is_terminal from status_options order by scope,sort_order`) defer rows.Close() var out []Row for rows.Next() { var id, sort int var scope, value, label string var term bool rows.Scan(&id, &scope, &value, &label, &sort, &term) out = append(out, Row{"ID": id, "Scope": scope, "Value": value, "Label": label, "Sort": sort, "Terminal": term}) } return out } func (a *App) workflowRules() []Row { rows, _ := a.DB.Query(`select id,name,trigger_name,condition_json,actions_json,enabled from workflow_rules order by name`) defer rows.Close() var out []Row for rows.Next() { var id int var name, trig, cond, actions string var en bool rows.Scan(&id, &name, &trig, &cond, &actions, &en) out = append(out, Row{"ID": id, "Name": name, "Trigger": trig, "Condition": cond, "Actions": actions, "Enabled": en}) } return out } func (a *App) questTemplates() []Row { rows, _ := a.DB.Query(`select qt.id,qt.type,qt.title_template,coalesce(qt.department_id,0),coalesce(d.name,''),qt.reward_percent,qt.enabled,qt.sort_order from quest_templates qt left join departments d on d.id=qt.department_id order by qt.sort_order`) defer rows.Close() var out []Row for rows.Next() { var id, deptID, sort int var typ, title, dept string var reward float64 var en bool rows.Scan(&id, &typ, &title, &deptID, &dept, &reward, &en, &sort) out = append(out, Row{"ID": id, "Type": typ, "Title": title, "DeptID": deptID, "Dept": dept, "Reward": reward, "Enabled": en, "Sort": sort}) } return out }