diff --git a/handlers/ticket_handler.go b/handlers/ticket_handler.go index 0c847db..4239a08 100644 --- a/handlers/ticket_handler.go +++ b/handlers/ticket_handler.go @@ -2,63 +2,145 @@ package handlers import ( "database/sql" + "fmt" "html/template" + "io" "log" "net/http" + "os" + "strconv" "synlotto-website/helpers" "synlotto-website/models" - "synlotto-website/storage" + "time" "github.com/gorilla/csrf" ) -func NewTicket(db *sql.DB) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - log.Println("➡️ New ticket form opened") +func AddTicket(db *sql.DB) http.HandlerFunc { + return helpers.AuthMiddleware(func(w http.ResponseWriter, r *http.Request) { + rows, err := db.Query(` + SELECT DISTINCT draw_date + FROM results_thunderball + ORDER BY draw_date DESC + `) + if err != nil { + log.Println("❌ Failed to load draw dates:", err) + http.Error(w, "Unable to load draw dates", http.StatusInternalServerError) + return + } + defer rows.Close() - tmpl := template.Must(template.ParseFiles( + var drawDates []string + for rows.Next() { + var date string + if err := rows.Scan(&date); err == nil { + drawDates = append(drawDates, date) + } + } + + context := helpers.TemplateContext(w, r) + context["csrfField"] = csrf.TemplateField(r) + context["DrawDates"] = drawDates + + tmpl := template.Must(template.New("").Funcs(helpers.TemplateFuncs()).ParseFiles( "templates/layout.html", - "templates/new_ticket.html", + "templates/account/tickets/add_ticket.html", )) - err := tmpl.ExecuteTemplate(w, "layout", map[string]interface{}{ - "csrfField": csrf.TemplateField(r), - "Page": "new_ticket", - "Data": nil, - }) + err = tmpl.ExecuteTemplate(w, "layout", context) if err != nil { - log.Println("❌ Template error:", err) + log.Println("❌ Template render error:", err) http.Error(w, "Error rendering form", http.StatusInternalServerError) } - } + }) } func SubmitTicket(db *sql.DB) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - if _, ok := helpers.GetCurrentUserID(r); !ok { + return helpers.AuthMiddleware(func(w http.ResponseWriter, r *http.Request) { + err := r.ParseMultipartForm(10 << 20) + if err != nil { + http.Error(w, "Invalid form", http.StatusBadRequest) + return + } + + userID, ok := helpers.GetCurrentUserID(r) + if !ok { http.Redirect(w, r, "/login", http.StatusSeeOther) return } - ticket := models.MyTicket{ - GameType: r.FormValue("game_type"), - DrawDate: r.FormValue("draw_date"), - Ball1: helpers.Atoi(r.FormValue("ball1")), - Ball2: helpers.Atoi(r.FormValue("ball2")), - Ball3: helpers.Atoi(r.FormValue("ball3")), - Ball4: helpers.Atoi(r.FormValue("ball4")), - Ball5: helpers.Atoi(r.FormValue("ball5")), - Bonus1: helpers.Nullable(helpers.Atoi(r.FormValue("bonus1"))), - Bonus2: helpers.Nullable(helpers.Atoi(r.FormValue("bonus2"))), + + game := r.FormValue("game_type") + drawDate := r.FormValue("draw_date") + purchaseMethod := r.FormValue("purchase_method") + purchaseDate := r.FormValue("purchase_date") + purchaseTime := r.FormValue("purchase_time") + + if purchaseTime != "" { + purchaseDate += "T" + purchaseTime } - if err := storage.InsertTicket(db, ticket); err != nil { - log.Println("❌ Failed to insert ticket:", err) - http.Error(w, "Error storing ticket", http.StatusInternalServerError) - return + imagePath := "" + file, handler, err := r.FormFile("ticket_image") + if err == nil && handler != nil { + defer file.Close() + filename := fmt.Sprintf("uploads/ticket_%d_%s", time.Now().UnixNano(), handler.Filename) + out, err := os.Create(filename) + if err == nil { + defer out.Close() + io.Copy(out, file) + imagePath = filename + } } - http.Redirect(w, r, "/", http.StatusSeeOther) - } + ballCount := 6 + bonusCount := 2 + + balls := make([][]int, ballCount) + bonuses := make([][]int, bonusCount) + + for i := 1; i <= ballCount; i++ { + balls[i-1] = helpers.ParseIntSlice(r.Form["ball"+strconv.Itoa(i)]) + } + for i := 1; i <= bonusCount; i++ { + bonuses[i-1] = helpers.ParseIntSlice(r.Form["bonus"+strconv.Itoa(i)]) + } + + lineCount := len(balls[0]) + for i := 0; i < lineCount; i++ { + var b [6]int + var bo [2]int + + for j := 0; j < ballCount; j++ { + if j < len(balls) && i < len(balls[j]) { + b[j] = balls[j][i] + } + } + for j := 0; j < bonusCount; j++ { + if j < len(bonuses) && i < len(bonuses[j]) { + bo[j] = bonuses[j][i] + } + } + + _, err := db.Exec(` + INSERT INTO my_tickets ( + user_id, game_type, draw_date, + ball1, ball2, ball3, ball4, ball5, ball6, + bonus1, bonus2, + purchase_method, purchase_date, image_path + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + `, + userID, game, drawDate, + b[0], b[1], b[2], b[3], b[4], b[5], + bo[0], bo[1], + purchaseMethod, purchaseDate, imagePath, + ) + if err != nil { + log.Println("❌ Insert failed:", err) + } + } + + http.Redirect(w, r, "/tickets", http.StatusSeeOther) + }) } func ListTickets(db *sql.DB) http.HandlerFunc {