Serve level_kinds from server, use for both validation and UI

This commit is contained in:
Ian Gulliver
2026-02-16 10:15:18 -08:00
parent 4c487a251b
commit d225a8c5d0
2 changed files with 14 additions and 22 deletions

26
main.go
View File

@@ -29,6 +29,11 @@ var schema string
var ( var (
htmlTemplates *template.Template htmlTemplates *template.Template
jsTemplates *texttemplate.Template jsTemplates *texttemplate.Template
levelKinds = map[string][]string{
"student": {"prefer", "prefer_not"},
"parent": {"must_not"},
"admin": {"must", "prefer", "prefer_not", "must_not"},
}
) )
func main() { func main() {
@@ -452,7 +457,7 @@ func handleTripMe(db *sql.DB) http.HandlerFunc {
students = []studentInfo{} students = []studentInfo{}
} }
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]any{"role": role, "students": students}) json.NewEncoder(w).Encode(map[string]any{"role": role, "students": students, "level_kinds": levelKinds})
} }
} }
@@ -893,22 +898,15 @@ func handleCreateConstraint(db *sql.DB) http.HandlerFunc {
http.Error(w, "students must be different", http.StatusBadRequest) http.Error(w, "students must be different", http.StatusBadRequest)
return return
} }
switch body.Level { validKinds := levelKinds[body.Level]
case "student": if validKinds == nil {
if body.Kind != "prefer" && body.Kind != "prefer_not" {
http.Error(w, "students may only use prefer or prefer not", http.StatusBadRequest)
return
}
case "parent":
if body.Kind != "must_not" {
http.Error(w, "parents may only use must not", http.StatusBadRequest)
return
}
case "admin":
default:
http.Error(w, "invalid level", http.StatusBadRequest) http.Error(w, "invalid level", http.StatusBadRequest)
return return
} }
if !slices.Contains(validKinds, body.Kind) {
http.Error(w, "invalid kind for level", http.StatusBadRequest)
return
}
if role != "admin" { if role != "admin" {
if body.Level != role { if body.Level != role {
http.Error(w, "forbidden", http.StatusForbidden) http.Error(w, "forbidden", http.StatusForbidden)

View File

@@ -411,11 +411,7 @@ async function loadStudents() {
const addRow = document.createElement('div'); const addRow = document.createElement('div');
addRow.className = 'constraint-add'; addRow.className = 'constraint-add';
const levelKinds = { const levelKinds = me.level_kinds;
student: ['prefer', 'prefer_not'],
parent: ['must_not'],
admin: ['must', 'prefer', 'prefer_not', 'must_not']
};
const levelSelect = document.createElement('wa-select'); const levelSelect = document.createElement('wa-select');
levelSelect.size = 'small'; levelSelect.size = 'small';
for (const level of ['student', 'parent', 'admin']) { for (const level of ['student', 'parent', 'admin']) {
@@ -618,9 +614,7 @@ async function renderMemberView(me) {
? { '': 'OK to room with', prefer: 'Would like to room with', prefer_not: 'Would prefer not to room with' } ? { '': 'OK to room with', prefer: 'Would like to room with', prefer_not: 'Would prefer not to room with' }
: { '': 'OK to room with', must_not: 'Not OK to room with' }; : { '': 'OK to room with', must_not: 'Not OK to room with' };
const kindOptions = me.role === 'student' const kindOptions = ['', ...me.level_kinds[me.role]];
? ['', 'prefer', 'prefer_not']
: ['', 'must_not'];
const pendingSelects = []; const pendingSelects = [];