Add support for custom error templates

This commit is contained in:
Andrea Fazzi 2019-12-09 14:18:31 +01:00
parent 3c19bbd4fb
commit 13f22aabbd
11 changed files with 114 additions and 12 deletions

View file

@ -6,7 +6,20 @@ import (
"git.andreafazzi.eu/andrea/oef/i18n"
)
type Error struct {
TemplateName string
Err error
}
func (e *Error) Error() string {
return e.Err.Error()
}
var (
RecordExists = errors.New("Record already exists!")
NotAuthorized = errors.New(i18n.Authorization["notAuthorized"]["it"])
RecordExists = errors.New("Record already exists!")
NotAuthorized = errors.New(i18n.Authorization["notAuthorized"]["it"])
CategoryExists = &Error{
TemplateName: "error_category_exists",
Err: errors.New(i18n.FlashMessages["categoryExists"]["it"]),
}
)

View file

@ -8,6 +8,9 @@ var (
"schoolExists": map[string]string{
"it": "Una scuola con questo codice meccanografico è già presente nella base dati!",
},
"categoryExists": map[string]string{
"it": "Un partecipante della stessa categoria è già stato iscritto dalla scuola.",
},
"notAuthorized": map[string]string{
"it": "L'utente non dispone delle autorizzazioni necessarie a visualizzare questa pagina.",
},

View file

@ -34,6 +34,7 @@ var (
&orm.Response{},
&orm.User{},
&orm.Category{},
&orm.Region{},
}
)
@ -74,6 +75,9 @@ func main() {
log.Println("Eventually write categories on DB...")
orm.CreateCategories()
log.Println("Eventually write regions on DB...")
orm.CreateRegions()
log.Println("Map models <-> handlers")
if err := orm.MapHandlers(models); err != nil {
panic(err)

View file

@ -149,6 +149,7 @@ func (model *Participant) Create(args map[string]string, w http.ResponseWriter,
return nil, err
}
// Check if participant exists
if user, err := participant.exists(); err == nil && user != nil {
if err := DB().Where("user_id = ?", user.ID).Find(&participant).Error; err != nil {
return nil, err
@ -162,8 +163,7 @@ func (model *Participant) Create(args map[string]string, w http.ResponseWriter,
return nil, err
}
participant.UserModifierCreate = NewUserModifierCreate(r)
// If user has "school" role get school id from token
if isSchool(r) {
schoolID, err := strconv.Atoi(getUserIDFromToken(r))
if err != nil {
@ -171,6 +171,22 @@ func (model *Participant) Create(args map[string]string, w http.ResponseWriter,
}
participant.SchoolID = uint(schoolID)
}
// Check if a participant of the same category exists
var school School
if err := DB().First(&school, participant.SchoolID).Error; err != nil {
return nil, err
}
hasCategory, err := school.HasCategory(participant)
if err != nil {
return nil, err
}
if hasCategory {
return nil, errors.CategoryExists
}
participant.UserModifierCreate = NewUserModifierCreate(r)
participant, err = CreateParticipant(participant)
if err != nil {
return nil, err
@ -284,6 +300,19 @@ func (model *Participant) Update(args map[string]string, w http.ResponseWriter,
return nil, err
}
// Check if a participant of the same category exists
var school School
if err := DB().First(&school, participant.(*Participant).SchoolID).Error; err != nil {
return nil, err
}
hasCategory, err := school.HasCategory(participant.(*Participant))
if err != nil {
return nil, err
}
if hasCategory {
return nil, errors.CategoryExists
}
if err := DB().Where(participant.(*Participant).ContestIDs).Find(&participant.(*Participant).Contests).Error; err != nil {
return nil, err
}

View file

@ -2,6 +2,7 @@ package orm
import (
"fmt"
"log"
"net/http"
"strings"
"time"
@ -248,3 +249,12 @@ func SaveSchool(school interface{}) (interface{}, error) {
}
return school, nil
}
func (model *School) HasCategory(participant *Participant) (bool, error) {
var participants []*Participant
log.Println(model)
if err := DB().Where("category_id = ? AND school_id = ? AND id <> ?", participant.CategoryID, model.ID, participant.ID).Find(&participants).Error; err != nil {
return false, err
}
return len(participants) > 0, nil
}

View file

@ -9,6 +9,7 @@ import (
"log"
"git.andreafazzi.eu/andrea/oef/config"
"git.andreafazzi.eu/andrea/oef/errors"
"github.com/gorilla/sessions"
"mime"
"net/http"
@ -228,12 +229,23 @@ func Use(r Renderer) {
}
func (rend *HTMLRenderer) writeError(w http.ResponseWriter, r *http.Request, data interface{}) {
t, ok := rend.templates["error"]
if !ok {
panic(fmt.Errorf("Error template not found! Can't proceed, sorry."))
}
var t *template.Template
log.Println(data.(*htmlTemplateData).Data.(error))
err, ok := data.(*htmlTemplateData).Data.(*errors.Error)
if ok {
t, ok = rend.templates[err.TemplateName]
if !ok {
panic(fmt.Errorf("Error template not found! Can't proceed, sorry."))
}
} else {
t, ok = rend.templates["error"]
if !ok {
panic(fmt.Errorf("Error template not found! Can't proceed, sorry."))
}
log.Println(data.(*htmlTemplateData).Data.(error))
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
e := t.ExecuteTemplate(w, "base", data)

View file

@ -0,0 +1,11 @@
{{ define "content" }}
<div class="container">
<h1 class="border-bottom">Errore</h1>
<p>
Si è verificato un errore durante la creazione o l'aggiornamento di un partecipante: <strong>{{.Data}}</strong>
</p>
<p>
Clicca {{all "Participant"|anchor "qui"}} per tornare all'elenco dei partecipanti.
</p>
</div>
{{ end }}

View file

@ -45,7 +45,8 @@
{{end}}
</div>
{{if $isSchool}}
{{if eq (len .Data) 2}}
<div class="row">
<div class="col-md-12">
@ -55,6 +56,7 @@
</div>
</div>
{{end}}
{{end}}
</div>

View file

@ -15,6 +15,8 @@
<dd class="col-sm-9">{{.Data.User.Username}}</dd>
<dt class="col-sm-3">Password</dt>
<dd class="col-sm-9">{{.Data.User.Password}}</dd>
<dt class="col-sm-3">Categoria</dt>
<dd class="col-sm-9">{{.Data.Category}}</dd>
{{if $creatorUser:=.Data.CreatedBy}}
<dt class="col-sm-3">Creato da</dt>
<dd class="col-sm-9">{{$creatorUser.Username}}[{{$creatorUser.Role}}] {{$.Data.CreatedAt|prettyDateTime}}</dd>
@ -45,6 +47,7 @@
</div>
</div>
{{if $isAdmin}}
<div class="row">
<div class="col-md-12">
@ -60,7 +63,6 @@
</div>
</div>
{{if $isAdmin}}
<div class="row">
<div class="col-md-12">

View file

@ -63,7 +63,19 @@
{{end}}
{{template "input" dict "options" ($codeOptions|yaml) "value" (.Data|field "Code") "update" $update}}
{{$options := ` { name: "Address",id: "school_address",label: "Indirizzo dell'istituto",placeholder: "Inserire via, numero civico e città",type: "text",required: "true"} `}}
{{template "input" dict "options" ($options|yaml) "value" (.Data|field "Address") "update" $update}}
{{$options := `
name: "region_id"
id: "region_id"
label: "Regione"
title: "Seleziona la regione"
required: "true"
`}}
{{template "select" dict "options" ($options|yaml) "data" (.Data|field "AllRegions") "selected" (.Data|field "SelectedRegion") "update" $update "form" $form}}
{{$options := ` { name: "Email",id: "school_email",label: "Indirizzo email",placeholder: "Inserire l'indirizzo di posta istituzionale",type: "email",required: "true"} `}}
{{template "input" dict "options" ($options|yaml) "value" (.Data|field "Email") "update" $update}}

View file

@ -41,6 +41,10 @@
<dd class="col-sm-9">{{.Data.Name}}</dd>
<dt class="col-sm-3">Codice meccanografico</dt>
<dd class="col-sm-9">{{.Data.Code}}</dd>
<dt class="col-sm-3">Indirizzo</dt>
<dd class="col-sm-9">{{.Data.Address}}</dd>
<dt class="col-sm-3">Regione</dt>
<dd class="col-sm-9">{{.Data.Region}}</dd>
<dt class="col-sm-3">Email</dt>
<dd class="col-sm-9">{{.Data.Email}}</dd>
{{if .Data.EmailSentDate}}