admin view routes and tasks

This commit is contained in:
2025-09-18 20:20:18 +02:00
parent e9efea447b
commit 32d25037c2
4 changed files with 113 additions and 13 deletions

View File

@@ -7,6 +7,11 @@ import (
"regexp" "regexp"
) )
type difficultyLevel struct {
ID int
LevelName string
}
func adminLoginHandler(w http.ResponseWriter, r *http.Request) { func adminLoginHandler(w http.ResponseWriter, r *http.Request) {
switch r.Method { switch r.Method {
case http.MethodGet: case http.MethodGet:
@@ -68,13 +73,11 @@ func isAdmin(w http.ResponseWriter, r *http.Request) bool {
if err != sql.ErrNoRows && err == nil { if err != sql.ErrNoRows && err == nil {
return true return true
} }
http.Redirect(w, r, "/admin/login", http.StatusSeeOther)
return false return false
} }
func adminHandler(w http.ResponseWriter, r *http.Request) { func adminHandler(w http.ResponseWriter, r *http.Request) {
if !isAdmin(w, r) { if !isAdmin(w, r) {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return return
} }
http.ServeFile(w, r, "templates/adminPanel.html") http.ServeFile(w, r, "templates/adminPanel.html")
@@ -82,10 +85,9 @@ func adminHandler(w http.ResponseWriter, r *http.Request) {
func adminTeamsHandler(w http.ResponseWriter, r *http.Request) { func adminTeamsHandler(w http.ResponseWriter, r *http.Request) {
if !isAdmin(w, r) { if !isAdmin(w, r) {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return return
} }
rows, err := db.Query("SELECT name, difficulty_levels.level_name, last_cipher, penalty FROM teams JOIN difficulty_levels ON teams.difficulty_level = difficulty_levels.id ORDER BY name") rows, err := db.Query("SELECT name, difficulty_levels.level_name, last_cipher, penalty FROM teams JOIN difficulty_levels ON teams.difficulty_level = difficulty_levels.id ORDER BY teams.difficulty_level, teams.name")
if err != nil { if err != nil {
http.Error(w, "Database error", http.StatusInternalServerError) http.Error(w, "Database error", http.StatusInternalServerError)
return return
@@ -112,7 +114,6 @@ func adminTeamsHandler(w http.ResponseWriter, r *http.Request) {
func AdminStartHandler(w http.ResponseWriter, r *http.Request) { func AdminStartHandler(w http.ResponseWriter, r *http.Request) {
if !isAdmin(w, r) { if !isAdmin(w, r) {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return return
} }
_, err := db.Exec("UPDATE teams SET last_cipher = 1, penalty = 0") _, err := db.Exec("UPDATE teams SET last_cipher = 1, penalty = 0")
@@ -127,3 +128,55 @@ func AdminStartHandler(w http.ResponseWriter, r *http.Request) {
} }
http.Redirect(w, r, "/admin/", http.StatusSeeOther) http.Redirect(w, r, "/admin/", http.StatusSeeOther)
} }
func AdminRouteHandler(w http.ResponseWriter, r *http.Request) {
if !isAdmin(w, r) {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
// Fetch all difficulty levels
rows, err := db.Query("SELECT id, level_name FROM difficulty_levels ORDER BY id")
if err != nil {
http.Error(w, "Database error", http.StatusInternalServerError)
return
}
defer rows.Close()
var difficultyLevels []difficultyLevel
for rows.Next() {
var level difficultyLevel
if err := rows.Scan(&level.ID, &level.LevelName); err != nil {
http.Error(w, "Database error", http.StatusInternalServerError)
return
}
difficultyLevels = append(difficultyLevels, level)
}
// For each difficulty level, fetch the corresponding tasks and their details
var routes []AdminRoutesTemplateS
for _, level := range difficultyLevels {
var route AdminRoutesTemplateS
rows, err := db.Query("SELECT tasks.order_num, CIPHERS.assignment, CIPHERS.clue, tasks.end_clue, POSITIONS.gps, POSITIONS.clue, CIPHERS.solution FROM TASKS JOIN CIPHERS ON TASKS.cipher_id = ciphers.id JOIN POSITIONS on TASKS.position_id = POSITIONS.id WHERE TASKS.difficulty_level=? ORDER BY TASKS.order_num;", level.ID)
if err != nil {
http.Error(w, "Database error", http.StatusInternalServerError)
return
}
defer rows.Close()
route.Name = level.LevelName
for rows.Next() {
var cipher CipherTemplateS
if err := rows.Scan(&cipher.Order, &cipher.Assignment, &cipher.HelpText, &cipher.FinalClue, &cipher.Coordinates, &cipher.PositionHint, &cipher.Solution); err != nil {
http.Error(w, "Database error", http.StatusInternalServerError)
return
}
route.Ciphers = append(route.Ciphers, cipher)
}
if err := rows.Err(); err != nil {
http.Error(w, "Database error", http.StatusInternalServerError)
return
}
routes = append(routes, route)
}
if err := AdminRoutesTemplate.Execute(w, routes); err != nil {
http.Error(w, "Template error", http.StatusInternalServerError)
return
}
}

View File

@@ -338,6 +338,7 @@ func main() {
http.HandleFunc("/admin/", adminHandler) http.HandleFunc("/admin/", adminHandler)
http.HandleFunc("/admin/teams", adminTeamsHandler) http.HandleFunc("/admin/teams", adminTeamsHandler)
http.HandleFunc("/admin/start", AdminStartHandler) http.HandleFunc("/admin/start", AdminStartHandler)
http.HandleFunc("/admin/routes", AdminRouteHandler)
fmt.Println("Server started at :8080") fmt.Println("Server started at :8080")
http.ListenAndServe(":8080", nil) http.ListenAndServe(":8080", nil)

View File

@@ -5,14 +5,15 @@ import (
) )
type CipherTemplateS struct { type CipherTemplateS struct {
Order uint Order uint
Assignment template.HTML Assignment template.HTML
HelpText string HelpText string
FinalClue string FinalClue string
Coordinates string Coordinates string
Solution string PositionHint string
Help int Solution string
Wrong bool Help int
Wrong bool
} }
type TeamTemplateS struct { type TeamTemplateS struct {
@@ -22,6 +23,12 @@ type TeamTemplateS struct {
Penalties int Penalties int
} }
type AdminRoutesTemplateS struct {
Name string
Ciphers []CipherTemplateS
}
var CipherTemplate = template.Must(template.ParseFiles("templates/assignment.html")) var CipherTemplate = template.Must(template.ParseFiles("templates/assignment.html"))
var TeamTemplate = template.Must(template.ParseFiles("templates/team.html")) var TeamTemplate = template.Must(template.ParseFiles("templates/team.html"))
var AdminTeamsTemplate = template.Must(template.ParseFiles("templates/adminTeams.html")) var AdminTeamsTemplate = template.Must(template.ParseFiles("templates/adminTeams.html"))
var AdminRoutesTemplate = template.Must(template.ParseFiles("templates/adminRoutes.html"))

View File

@@ -0,0 +1,39 @@
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<title>Trasy</title>
</head>
<body>
<h1>Trasy</h1>
{{range .}}
<h2>{{.Name}}</h2>
<table border="1">
<tr>
<th>Pořadí</th>
<th>Souřadnice</th>
<th>Nápověda pozice</th>
<th>Zadání</th>
<th>Nápověda</th>
<th>Řešení</th>
<th>Cílová indicie</th>
</tr>
{{range .Ciphers}}
<tr>
<td>{{.Order}}</td>
<td>{{.Coordinates}}</td>
<td>{{.PositionHint}}</td>
<td>{{.Assignment}}</td>
<td>{{.HelpText}}</td>
<td>{{.Solution}}</td>
<td>{{.FinalClue}}</td>
</tr>
{{end}}
</table>
<hr>
{{end}}
</body>
</html>