Show user friendly error messages on homepage.

This commit is contained in:
Vojtěch Káně
2021-07-03 16:22:17 +02:00
parent 08b8aad09d
commit b0e8a43331
4 changed files with 94 additions and 31 deletions

View File

@@ -14,12 +14,36 @@ import (
"vkane.cz/tinyquiz/pkg/rtcomm" "vkane.cz/tinyquiz/pkg/rtcomm"
) )
func (app *application) home(w http.ResponseWriter, r *http.Request, params httprouter.Params) { func (app *application) homeSuccess(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
app.home(w, r, homeForm{}, http.StatusOK)
}
type homeForm struct {
Join struct {
Code string
Name string
Errors []string
}
NewSession struct {
Code string
Name string
Errors []string
}
NewGame struct {
Title string
Name string
Errors []string
}
}
func (app *application) home(w http.ResponseWriter, r *http.Request, formData homeForm, status int) {
type homeData struct { type homeData struct {
Stats model.Stats Stats model.Stats
Form homeForm
templateData templateData
} }
td := &homeData{} td := &homeData{}
td.Form = formData
setDefaultTemplateData(&td.templateData) setDefaultTemplateData(&td.templateData)
if stats, err := app.model.GetStats(r.Context()); err == nil { if stats, err := app.model.GetStats(r.Context()); err == nil {
@@ -28,7 +52,7 @@ func (app *application) home(w http.ResponseWriter, r *http.Request, params http
app.serverError(w, err) app.serverError(w, err)
return return
} }
w.WriteHeader(status)
app.render(w, r, "home.page.tmpl.html", td) app.render(w, r, "home.page.tmpl.html", td)
} }
@@ -40,9 +64,13 @@ func (app *application) play(w http.ResponseWriter, r *http.Request, params http
var code = strings.TrimSpace(params.ByName("code")) var code = strings.TrimSpace(params.ByName("code"))
var player = strings.ToLower(strings.TrimSpace(r.PostForm.Get("player"))) var player = strings.ToLower(strings.TrimSpace(r.PostForm.Get("player")))
var form homeForm
form.Join.Code = code
form.Join.Name = player
if len(player) < 1 { if len(player) < 1 {
app.clientError(w, http.StatusBadRequest) form.Join.Errors = []string{"Zadejte jméno hráče"}
app.home(w, r, form, http.StatusBadRequest)
return return
} }
@@ -61,10 +89,12 @@ func (app *application) play(w http.ResponseWriter, r *http.Request, params http
http.Redirect(w, r, "/game/"+url.PathEscape(player.ID.String()), http.StatusSeeOther) http.Redirect(w, r, "/game/"+url.PathEscape(player.ID.String()), http.StatusSeeOther)
return return
} else if errors.Is(err, model.NoSuchEntity) { } else if errors.Is(err, model.NoSuchEntity) {
app.clientError(w, http.StatusNotFound) form.Join.Errors = []string{"Hra s tímto kódem nebyla nalezena"}
app.home(w, r, form, http.StatusNotFound)
return return
} else if errors.Is(err, model.ConstraintViolation) { } else if errors.Is(err, model.ConstraintViolation) {
app.clientError(w, http.StatusForbidden) form.Join.Errors = []string{"Hráč s tímto jménem již existuje"}
app.home(w, r, form, http.StatusForbidden)
return return
} else { } else {
app.serverError(w, err) app.serverError(w, err)
@@ -81,9 +111,13 @@ func (app *application) createSession(w http.ResponseWriter, r *http.Request, pa
var code = strings.TrimSpace(r.PostForm.Get("code")) var code = strings.TrimSpace(r.PostForm.Get("code"))
var player = strings.ToLower(strings.TrimSpace(r.PostForm.Get("organiser"))) var player = strings.ToLower(strings.TrimSpace(r.PostForm.Get("organiser")))
var form homeForm
form.NewSession.Code = code
form.NewSession.Name = player
if len(player) < 1 { if len(player) < 1 {
app.clientError(w, http.StatusBadRequest) form.NewSession.Errors = []string{"Zadejte jméno organizátora"}
app.home(w, r, form, http.StatusBadRequest)
return return
} }
@@ -97,7 +131,8 @@ func (app *application) createSession(w http.ResponseWriter, r *http.Request, pa
return return
} }
} else if errors.Is(err, model.NoSuchEntity) { } else if errors.Is(err, model.NoSuchEntity) {
app.clientError(w, http.StatusNotFound) form.NewSession.Errors = []string{"Hra s tímto kódem nebyla nalezena"}
app.home(w, r, form, http.StatusNotFound)
return return
} else { } else {
app.serverError(w, err) app.serverError(w, err)
@@ -253,9 +288,13 @@ func (app *application) createGame(w http.ResponseWriter, r *http.Request, param
} }
var name = r.PostFormValue("name") var name = r.PostFormValue("name")
var author = r.PostFormValue("author") var author = r.PostFormValue("author")
var form homeForm
form.NewGame.Title = name
form.NewGame.Name = author
file, _, err := r.FormFile("game") file, _, err := r.FormFile("game")
if err != nil { if err != nil {
app.clientError(w, http.StatusBadRequest) form.NewGame.Errors = []string{"Nahrajte soubor s otázkami"}
app.home(w, r, form, http.StatusBadRequest)
return return
} }
@@ -267,11 +306,9 @@ func (app *application) createGame(w http.ResponseWriter, r *http.Request, param
app.serverError(w, err) app.serverError(w, err)
return return
} }
} else if errors.Is(err, gameCreator.ErrInvalidSyntax) || errors.Is(err, gameCreator.ErrTooManyQuestions) || errors.Is(err, gameCreator.ErrTooManyChoices) {
app.clientError(w, http.StatusBadRequest)
return
} else { } else {
app.clientError(w, http.StatusBadRequest) form.NewGame.Errors = []string{"Soubor s otázkami není v pořádku"}
app.home(w, r, form, http.StatusBadRequest)
return return
} }
} }

View File

@@ -101,7 +101,7 @@ func main() {
}() }()
mux := httprouter.New() mux := httprouter.New()
mux.GET("/", app.home) mux.GET("/", app.homeSuccess)
mux.POST("/play/:code", app.play) mux.POST("/play/:code", app.play)
mux.POST("/session", app.createSession) mux.POST("/session", app.createSession)
mux.GET("/game/:playerUid", app.game) mux.GET("/game/:playerUid", app.game)

View File

@@ -22,28 +22,49 @@
</section> </section>
<section> <section>
<h1>Připojit se ke hře</h1> <h1>Připojit se ke hře</h1>
<form id="join" method="post"> {{- with .Form.Join }}
<label>Kód hry: <input type="text" name="code" placeholder="Kód hry"></label> {{- with .Errors }}
<label>Jméno hráče: <input type="text" name="player" placeholder="Jméno"></label> <ul class="error">
<input type="submit" value="Připojit do hry"> {{ range . }}<li>{{ . }}</li>{{ end }}
</form> </ul>
{{- end }}
<form id="join" method="post">
<label>Kód hry: <input type="text" name="code" placeholder="Kód hry" required value="{{ .Code }}"></label>
<label>Jméno hráče: <input type="text" name="player" placeholder="Jméno" required value="{{ .Name }}"></label>
<input type="submit" value="Připojit do hry">
</form>
{{- end }}
</section> </section>
<section> <section>
<h1>Zorganizovat novou hru</h1> <h1>Zorganizovat novou hru</h1>
<form id="play" method="post" action="/session"> {{- with .Form.NewSession }}
<label>Kód kvízu: <input type="text" name="code" placeholder="Kód kvizu"></label> {{- with .Errors }}
<label>Jméno organizátora: <input type="text" name="organiser" placeholder="Jméno"></label> <ul class="error">
<input type="submit" value="Začit hrát"> {{ range . }}<li>{{ . }}</li>{{ end }}
</form> </ul>
{{- end }}
<form id="play" method="post" action="/session">
<label>Kód kvízu: <input type="text" name="code" placeholder="Kód kvizu" required value="{{ .Code }}"></label>
<label>Jméno organizátora: <input type="text" name="organiser" placeholder="Jméno" required value="{{ .Name }}"></label>
<input type="submit" value="Začit hrát">
</form>
{{- end }}
</section> </section>
<section> <section>
<h1>Vytvořit nový kvíz</h1> {{- with .Form.NewGame }}
<p>Stáhnout <a href="/template" download>šablonu nového kvízu</a></p> {{- with .Errors }}
<form id="new" enctype="multipart/form-data" method="post" action="/game"> <ul class="error">
<label>Jméno kvízu: <input type="text" name="name" placeholder="Jméno kvízu"></label> {{ range . }}<li>{{ . }}</li>{{ end }}
<label>Jméno autora: <input type="text" name="author" placeholder="Jméno"></label> </ul>
<label>Kvíz: <input type="file" name="game" accept="text/csv"></label> {{- end }}
<input type="submit" value="Vytvořit"> <h1>Vytvořit nový kvíz</h1>
</form> <p>Stáhnout <a href="/template" download>šablonu nového kvízu</a></p>
<form id="new" enctype="multipart/form-data" method="post" action="/game">
<label>Jméno kvízu: <input type="text" name="name" placeholder="Jméno kvízu" required value="{{ .Title }}"></label>
<label>Jméno autora: <input type="text" name="author" placeholder="Jméno" required value="{{ .Name }}"></label>
<label>Kvíz: <input type="file" name="game" accept="text/csv" required></label>
<input type="submit" value="Vytvořit">
</form>
{{- end }}
</section> </section>
{{ end -}} {{ end -}}

View File

@@ -16,3 +16,8 @@ section {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
.error {
color: red;
font-weight: bold;
}