Added syndicate creation and invite logic

- Implemented `CreateSyndicate` with transaction support
- Added `InviteToSyndicate` with membership check and invite insert
- Created syndicate invite model and DB logic for accepting/declining
- Ensured consistent error handling with `fmt.Errorf`
- Cleaned up unused invite handlers/routes
This commit is contained in:
2025-04-04 10:26:24 +01:00
parent df6608dda5
commit ef4478e8a6
2 changed files with 58 additions and 17 deletions

View File

@@ -3,35 +3,46 @@ package handlers
import (
"database/sql"
"net/http"
"strconv"
"synlotto-website/helpers"
"synlotto-website/models"
"synlotto-website/storage"
)
func SyndicateInviteHandler(db *sql.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
syndicateID := helpers.Atoi(r.FormValue("syndicate_id"))
recipientUsername := r.FormValue("username")
senderID, ok := helpers.GetCurrentUserID(r)
userID, ok := helpers.GetCurrentUserID(r)
if !ok {
helpers.RenderError(w, r, 403)
helpers.RenderError(w, r, http.StatusForbidden)
return
}
recipient := models.GetUserByUsername(recipientUsername)
if recipient == nil {
helpers.SetFlash(w, r, "User not found")
http.Redirect(w, r, "/account/syndicates", http.StatusSeeOther)
return
}
switch r.Method {
case http.MethodGet:
syndicateID := helpers.Atoi(r.URL.Query().Get("id"))
data := BuildTemplateData(db, w, r)
context := helpers.TemplateContext(w, r, data)
context["SyndicateID"] = syndicateID
err := storage.InviteUserToSyndicate(db, syndicateID, recipient.Id, senderID)
if err != nil {
helpers.SetFlash(w, r, "Failed to invite user")
} else {
helpers.SetFlash(w, r, "Invitation sent to "+recipientUsername)
tmpl := helpers.LoadTemplateFiles("invite-syndicate.html", "templates/syndicates/invite.html")
err := tmpl.ExecuteTemplate(w, "layout", context)
if err != nil {
helpers.RenderError(w, r, 500)
}
case http.MethodPost:
syndicateID := helpers.Atoi(r.FormValue("syndicate_id"))
username := r.FormValue("username")
err := storage.InviteToSyndicate(db, userID, syndicateID, username)
if err != nil {
helpers.SetFlash(w, r, "Failed to send invite: "+err.Error())
} else {
helpers.SetFlash(w, r, "Invite sent successfully.")
}
http.Redirect(w, r, "/account/syndicates/view?id="+strconv.Itoa(syndicateID), http.StatusSeeOther)
default:
helpers.RenderError(w, r, http.StatusMethodNotAllowed)
}
http.Redirect(w, r, "/account/syndicates", http.StatusSeeOther)
}
}

View File

@@ -228,3 +228,33 @@ func CreateSyndicate(db *sql.DB, ownerID int, name, description string) (int64,
return syndicateID, nil
}
func InviteToSyndicate(db *sql.DB, inviterID, syndicateID int, username string) error {
var inviteeID int
err := db.QueryRow(`
SELECT id FROM users WHERE username = ?
`, username).Scan(&inviteeID)
if err == sql.ErrNoRows {
return fmt.Errorf("user not found")
} else if err != nil {
return err
}
var count int
err = db.QueryRow(`
SELECT COUNT(*) FROM syndicate_members
WHERE syndicate_id = ? AND user_id = ?
`, syndicateID, inviteeID).Scan(&count)
if err != nil {
return err
}
if count > 0 {
return fmt.Errorf("user already a member or invited")
}
_, err = db.Exec(`
INSERT INTO syndicate_members (syndicate_id, user_id, is_manager, status)
VALUES (?, ?, 0, 'invited')
`, syndicateID, inviteeID)
return err
}