diff options
Diffstat (limited to 'internal')
-rw-r--r-- | internal/database/repos/main.go | 3 | ||||
-rw-r--r-- | internal/database/repos/questions.go | 39 | ||||
-rw-r--r-- | internal/handlers/main.go | 94 | ||||
-rw-r--r-- | internal/models/models.go | 6 | ||||
-rw-r--r-- | internal/server/router.go | 2 |
5 files changed, 111 insertions, 33 deletions
diff --git a/internal/database/repos/main.go b/internal/database/repos/main.go index f6835c7..e49d303 100644 --- a/internal/database/repos/main.go +++ b/internal/database/repos/main.go @@ -2,12 +2,11 @@ package repos import ( "github.com/jmoiron/sqlx" - "demoon/internal/models" ) type FullRepo interface { DefaultsRepo - DBGetQuestion(id string) (*models.Question, error) + QuestionsRepo } type Provider struct { diff --git a/internal/database/repos/questions.go b/internal/database/repos/questions.go index d9978a4..9d0396e 100644 --- a/internal/database/repos/questions.go +++ b/internal/database/repos/questions.go @@ -1,9 +1,46 @@ package repos -import "demoon/internal/models" +import ( + "demoon/internal/models" + "fmt" +) type QuestionsRepo interface { DBGetQuestion(id string) (*models.Question, error) + DBGetMixedUbung(id uint32) (*models.MixedUbung, error) + DBListMixed(limit uint32) ([]models.MixedUbung, error) + DBGetQuestionsByMixedID(id string) ([]models.Question, error) +} + +func (p *Provider) DBGetMixedUbung(id uint32) (*models.MixedUbung, error) { + var ubung models.MixedUbung + err := p.db.Get(&ubung, "SELECT * FROM Table_Mixed WHERE mixedid = ?", id) + if err != nil { + return nil, err + } + return &ubung, nil +} + +func (p *Provider) DBListMixed(limit uint32) ([]models.MixedUbung, error) { + var ubungs []models.MixedUbung + query := "SELECT * FROM Table_Mixed ORDER BY MixedID" + if limit > 0 { + query = fmt.Sprintf("SELECT * FROM Table_Mixed ORDER BY MixedID LIMIT %d", limit) + } + err := p.db.Select(&ubungs, query) + if err != nil { + return nil, err + } + return ubungs, nil +} + +func (p *Provider) DBGetQuestionsByMixedID(id string) ([]models.Question, error) { + var questions []models.Question + err := p.db.Select(&questions, "SELECT * FROM questions WHERE mixed_id = ? ORDER BY id", id) + if err != nil { + return nil, err + } + return questions, nil } func (p *Provider) DBGetQuestion(id string) (*models.Question, error) { diff --git a/internal/handlers/main.go b/internal/handlers/main.go index 4a64380..34f37d9 100644 --- a/internal/handlers/main.go +++ b/internal/handlers/main.go @@ -13,10 +13,9 @@ import ( // Handlers structure type Handlers struct { - cfg config.Config - log *slog.Logger - repo repos.FullRepo - showNext bool // Tracks when to show next button + cfg config.Config + log *slog.Logger + repo repos.FullRepo } // NewHandlers constructor @@ -80,16 +79,23 @@ func (h *Handlers) HandleAnswer(w http.ResponseWriter, r *http.Request) { return } selectedIdx++ // in db index starts from 1 - h.showNext = true - feedback := "" + // Render feedback section with full question state + tmpl, err := template.ParseGlob("components/*.html") + if err != nil { + abortWithError(w, err.Error()) + return + } + question.Status = 2 if selectedIdx == int(question.CorrectIndex) { - feedback = `<div data-testid="feedback" class="feedback">Correct! 🎉</div>` - } else { - feedback = `<div data-testid="feedback" class="feedback">Wrong answer! The correct answer was: ` + getCorrectOption(question) + `</div>` + question.Status = 1 } + // Execute template with question data including status w.Header().Set("Content-Type", "text/html") - w.Write([]byte(feedback)) + err = tmpl.ExecuteTemplate(w, "main", question) + if err != nil { + h.log.Error("failed to render feedback template", "error", err) + } } func getCorrectOption(q *models.Question) string { @@ -107,10 +113,39 @@ func getCorrectOption(q *models.Question) string { } } +func (h *Handlers) HandleMixedUbung(w http.ResponseWriter, r *http.Request) { + mixedID := r.URL.Query().Get("id") + if mixedID == "" { + h.log.Error("missing mixed ID parameter") + abortWithError(w, "Missing exercise ID") + return + } + + questions, err := h.repo.DBGetQuestionsByMixedID(mixedID) + if err != nil { + h.log.Error("failed to get questions for mixed exercise", "error", err, "mixed_id", mixedID) + abortWithError(w, "Failed to load exercise") + return + } + + if len(questions) == 0 { + h.log.Error("no questions found for mixed exercise", "mixed_id", mixedID) + abortWithError(w, "Exercise contains no questions") + return + } + + // Render first question in the sequence + h.renderQuestion(w, &questions[0]) +} + func (h *Handlers) HandleNextQuestion(w http.ResponseWriter, r *http.Request) { currentID := r.URL.Query().Get("current_id") - nextID, _ := strconv.Atoi(currentID) - nextID++ + currID, err := strconv.Atoi(currentID) + if err != nil { + h.log.Error("invalid current question ID", "error", err, "current_id", currentID) + currID = 0 // Start from first question if invalid ID + } + nextID := currID + 1 question, err := h.repo.DBGetQuestion(strconv.Itoa(nextID)) if err != nil { @@ -119,7 +154,8 @@ func (h *Handlers) HandleNextQuestion(w http.ResponseWriter, r *http.Request) { return } - h.showNext = false // Reset flag for new question + h.log.Debug("returning new question", "q", question) + h.renderQuestion(w, question) } @@ -133,34 +169,32 @@ func (h *Handlers) renderQuestion(w http.ResponseWriter, question *models.Questi // Add ShowNext flag to template data type TemplateData struct { *models.Question - ShowNext bool - Correct bool } - err = tmpl.ExecuteTemplate(w, "main", &TemplateData{ - Question: question, - ShowNext: h.showNext, - }) + err = tmpl.ExecuteTemplate(w, "question", question) if err != nil { h.log.Error("failed to render template", "error", err) } - question, err = h.repo.DBGetQuestion("1") - if err != nil { - h.log.Error("failed to get question", "error", err) - abortWithError(w, "Question not found") - return - } } func (h *Handlers) MainPage(w http.ResponseWriter, r *http.Request) { - question, err := h.repo.DBGetQuestion("1") + ubungs, err := h.repo.DBListMixed(10) if err != nil { - h.log.Error("failed to get question", "error", err) - abortWithError(w, "Question not found") + h.log.Error("failed to get mixed ubungs", "error", err) + abortWithError(w, "Failed to load exercises") return } - h.showNext = false - h.renderQuestion(w, question) + tmpl, err := template.ParseGlob("components/*.html") + if err != nil { + abortWithError(w, err.Error()) + return + } + + w.Header().Set("Content-Type", "text/html") + err = tmpl.ExecuteTemplate(w, "main", ubungs) + if err != nil { + h.log.Error("failed to render template", "error", err) + } } diff --git a/internal/models/models.go b/internal/models/models.go index 8e30a6c..7cef85e 100644 --- a/internal/models/models.go +++ b/internal/models/models.go @@ -15,4 +15,10 @@ type ( ExamID uint32 `db:"exam_id"` MixedID uint32 `db:"mixed_id"` } + MixedUbung struct { + ID uint32 `db:"MixedID"` + Name string `db:"MixedName"` + Status int `db:"MixedStatus"` + LevelID uint32 `db:"LevelID"` + } ) diff --git a/internal/server/router.go b/internal/server/router.go index 43a29b9..bb73e71 100644 --- a/internal/server/router.go +++ b/internal/server/router.go @@ -23,6 +23,8 @@ func (srv *server) ListenToRequests() { mux.HandleFunc("GET /ping", h.Ping) mux.HandleFunc("GET /", h.MainPage) mux.HandleFunc("POST /answer", h.HandleAnswer) + mux.HandleFunc("GET /next-question", h.HandleNextQuestion) + mux.HandleFunc("GET /mixed", h.HandleMixedUbung) // mux.HandleFunc("POST /login", h.HandleLogin) // mux.HandleFunc("POST /signup", h.HandleSignup) |