Improve flash message handling

main
Jan Dittberner 2 years ago
parent be14a37b4d
commit 99a2cde144

@ -261,7 +261,11 @@ func (app *application) newMotionSubmit(w http.ResponseWriter, r *http.Request)
app.jobScheduler.Reschedule(JobIDCloseDecisions, JobIDRemindVoters)
app.sessionManager.Put(r.Context(), "flash", fmt.Sprintf("Started new motion %s: %s", decision.Tag, decision.Title))
app.addFlash(r, &FlashMessage{
Variant: flashSuccess,
Title: "New motion started",
Message: fmt.Sprintf("Started new motion %s: %s", decision.Tag, decision.Title),
})
http.Redirect(w, r, "/motions/", http.StatusSeeOther)
}
@ -357,11 +361,11 @@ func (app *application) editMotionSubmit(w http.ResponseWriter, r *http.Request)
app.jobScheduler.Reschedule(JobIDCloseDecisions, JobIDRemindVoters)
app.sessionManager.Put(
r.Context(),
"flash",
fmt.Sprintf("The motion %s has been modified!", decision.Tag),
)
app.addFlash(r, &FlashMessage{
Variant: flashInfo,
Title: "Motion modified",
Message: fmt.Sprintf("The motion %s has been modified!", decision.Tag),
})
http.Redirect(w, r, "/motions/", http.StatusSeeOther)
}
@ -412,11 +416,11 @@ func (app *application) withdrawMotionSubmit(w http.ResponseWriter, r *http.Requ
app.jobScheduler.Reschedule(JobIDCloseDecisions, JobIDRemindVoters)
app.sessionManager.Put(
r.Context(),
"flash",
fmt.Sprintf("Motion %s has been withdrawn!", motion.Tag),
)
app.addFlash(r, &FlashMessage{
Variant: flashWarning,
Title: "Motion withdrawn",
Message: fmt.Sprintf("The motion %s has been withdrawn!", motion.Tag),
})
http.Redirect(w, r, "/motions/", http.StatusSeeOther)
}
@ -490,11 +494,11 @@ func (app *application) voteSubmit(w http.ResponseWriter, r *http.Request) {
Decision: motion, User: user, Choice: choice,
})
app.sessionManager.Put(
r.Context(),
"flash",
fmt.Sprintf("Your vote for motion %s has been registered.", motion.Tag),
)
app.addFlash(r, &FlashMessage{
Variant: flashSuccess,
Title: "Vote registered",
Message: fmt.Sprintf("Your vote for motion %s has been registered.", motion.Tag),
})
http.Redirect(w, r, "/motions/", http.StatusSeeOther)
}
@ -598,11 +602,15 @@ func (app *application) proxyVoteSubmit(w http.ResponseWriter, r *http.Request)
Decision: motion, User: user, Voter: voter, Choice: form.Choice, Justification: form.Justification,
})
app.sessionManager.Put(
r.Context(),
"flash",
fmt.Sprintf("Your proxy vote for %s for motion %s has been registered.", voter.Name, motion.Tag),
)
app.addFlash(r, &FlashMessage{
Variant: flashSuccess,
Title: "Proxy vote registered",
Message: fmt.Sprintf(
"Your proxy vote for %s for motion %s has been registered.",
voter.Name,
motion.Tag,
),
})
http.Redirect(w, r, "/motions/", http.StatusSeeOther)
}
@ -735,11 +743,11 @@ func (app *application) editUserSubmit(w http.ResponseWriter, r *http.Request) {
return
}
app.sessionManager.Put(
r.Context(),
"flash",
fmt.Sprintf("User %s has been modified.", userToEdit.Name),
)
app.addFlash(r, &FlashMessage{
Variant: flashInfo,
Title: "User modified",
Message: fmt.Sprintf("User %s has been modified.", userToEdit.Name),
})
http.Redirect(w, r, "/users/", http.StatusSeeOther)
}
@ -835,11 +843,15 @@ func (app *application) userAddEmailSubmit(w http.ResponseWriter, r *http.Reques
return
}
app.sessionManager.Put(
r.Context(),
"flash",
fmt.Sprintf("Added email address %s for user %s", form.EmailAddress, userToEdit.Name),
)
app.addFlash(r, &FlashMessage{
Variant: flashSuccess,
Title: "Email address added",
Message: fmt.Sprintf(
"Added email address %s for user %s",
form.EmailAddress,
userToEdit.Name,
),
})
http.Redirect(w, r, fmt.Sprintf("/users/%d/", userToEdit.ID), http.StatusSeeOther)
}
@ -860,7 +872,7 @@ func (app *application) newUserForm(_ http.ResponseWriter, _ *http.Request) {
}
func (app *application) newUserSubmit(_ http.ResponseWriter, _ *http.Request) {
// TODO: implement userDeleteEmailSubmit
// TODO: implement newUserSubmit
panic("not implemented")
}
@ -928,11 +940,11 @@ func (app *application) deleteUserSubmit(w http.ResponseWriter, r *http.Request)
return
}
app.sessionManager.Put(
r.Context(),
"flash",
fmt.Sprintf("User %s has been deleted.", userToDelete.Name),
)
app.addFlash(r, &FlashMessage{
Variant: flashWarning,
Title: "User deleted",
Message: fmt.Sprintf("User %s has been deleted.", userToDelete.Name),
})
http.Redirect(w, r, "/users/", http.StatusSeeOther)
}

@ -126,7 +126,7 @@ type templateData struct {
User *models.User
Users []*models.User
Request *http.Request
Flash string
Flashes []FlashMessage
Form any
ActiveNav topLevelNavItem
ActiveSubNav subLevelNavItem
@ -145,7 +145,7 @@ func (app *application) newTemplateData(
User: user,
ActiveNav: nav,
ActiveSubNav: subNav,
Flash: app.sessionManager.PopString(r.Context(), "flash"),
Flashes: app.flashes(r),
CSRFToken: nosurf.Token(r),
}
}
@ -253,3 +253,44 @@ func getPEMClientCert(r *http.Request) (string, error) {
return clientCertPEM.String(), nil
}
type FlashVariant string
const (
flashWarning FlashVariant = "warning"
flashInfo FlashVariant = "info"
flashSuccess FlashVariant = "success"
flashError FlashVariant = "error"
)
type FlashMessage struct {
Variant FlashVariant
Title string
Message string
}
func (app *application) addFlash(r *http.Request, message *FlashMessage) {
flashes := app.flashes(r)
flashes = append(flashes, *message)
app.sessionManager.Put(
r.Context(),
"flashes",
flashes,
)
}
func (app *application) flashes(r *http.Request) []FlashMessage {
flashInstance := app.sessionManager.Pop(r.Context(), "flashes")
if flashInstance != nil {
flashes, ok := flashInstance.([]FlashMessage)
if ok {
return flashes
}
}
return make([]FlashMessage, 0)
}

@ -23,6 +23,7 @@ import (
"crypto/tls"
"crypto/x509"
"database/sql"
"encoding/gob"
"flag"
"fmt"
"html/template"
@ -103,6 +104,8 @@ func main() {
sessionManager.Cookie.SameSite = http.SameSiteStrictMode
sessionManager.Cookie.Secure = true
gob.Register([]FlashMessage{})
app := &application{
errorLog: errorLog,
infoLog: infoLog,

@ -15,9 +15,7 @@
<img src="/static/images/CAcert-logo-colour.svg" alt="CAcert" height="40rem"/>
</div>
<div class="ui text container">
<h1 class="ui header">
{{ template "title" . }}
</h1>
<h1 class="ui header">CAcert Board Voting System</h1>
{{ with .User }}
<div class="ui label">
<i class="id card outline icon"></i>
@ -29,14 +27,15 @@
</header>
{{ template "nav" . }}
<main class="ui container">
{{ with .Flash }}
{{ with .Flashes }}
<div class="basic segment">
<div class="ui info message">
<i class="close icon"></i>
<div class="ui list">
<div class="ui item">{{ . }}</div>
{{ range . }}
<div class="ui {{ .Variant }} message">
<i class="close icon"></i>
<div class="header">{{ .Title }}</div>
<p>{{ .Message }}</p>
</div>
</div>
{{ end }}
</div>
{{ end }}
{{ template "main" . }}

Loading…
Cancel
Save