Members: edit - archive/restore - delete

This commit is contained in:
William Bouzourène 2025-01-13 17:13:55 +01:00
parent 6d35cd472d
commit cf2c70df0d
4 changed files with 285 additions and 42 deletions

View file

@ -58,11 +58,11 @@ func MemberShow(c *fiber.Ctx) error {
} }
var person models.Person var person models.Person
result := db.Preload("Section").Find( result := db.Unscoped().Preload("Section").Find(
&person, "id = ? AND is_member", id, true, &person, "id = ? AND is_member", id, true,
) )
if errors.Is(result.Error, gorm.ErrRecordNotFound) { if result.RowsAffected < 1 {
return fiber.NewError(fiber.StatusNotFound, "Not found") return fiber.NewError(fiber.StatusNotFound, "Not found")
} }
@ -192,3 +192,224 @@ func MemberAdd(c *fiber.Ctx) error {
"Errors": errors, "Errors": errors,
}) })
} }
func MemberEdit(c *fiber.Ctx) error {
id := c.Params("id")
db, err := helpers.GetDatabase()
if err != nil {
return err
}
var person models.Person
result := db.Find(&person, "id = ?", id)
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return fiber.NewError(fiber.StatusNotFound, "Not found")
}
if result.Error != nil {
return result.Error
}
title := fmt.Sprintf(
"%s %s | Modifier membre",
person.LastName,
person.LastName,
)
var sections []models.Section
db.Order("name collate nocase asc").Find(
&sections,
"contains_members = ?",
true,
)
var errors []string
if c.Method() == "POST" {
data := PersonValidation{
LastName: c.FormValue("last_name"),
FirstName: c.FormValue("first_name"),
Email: c.FormValue("email"),
Phone: c.FormValue("phone"),
Mobile: c.FormValue("mobile"),
Address1: c.FormValue("address1"),
Address2: c.FormValue("address2"),
PostalCode: c.FormValue("postal_code"),
City: c.FormValue("city"),
Section: c.FormValue("section"),
}
validate := validator.New()
validErrs := validate.Struct(data)
if validErrs != nil {
for _, validErr := range validErrs.(validator.ValidationErrors) {
switch validErr.Field() {
case "LastName":
errors = append(errors, "Le nom de famille est requis et ne peut pas contenir plus de 100 caractères")
case "FirstName":
errors = append(errors, "Le prénom est requis et ne peut pas contenir plus de 100 caractères")
case "Email":
if len(data.Email) > 0 {
errors = append(errors, "L'adresse email doit être valide")
}
case "Phone":
errors = append(errors, "Le numéro de téléphone fixe est trop long")
case "Mobile":
errors = append(errors, "Le numéro de téléphone mobile est trop long")
case "Address1":
errors = append(errors, "La ligne 1 de l'adresse est trop longue")
case "Address2":
errors = append(errors, "La ligne 2 de l'adresse est trop longue")
case "PostalCode":
if len(data.PostalCode) > 0 {
errors = append(errors, "Le code postal n'est pas valide")
}
case "City":
errors = append(errors, "Le lieu est trop long")
case "Section":
errors = append(errors, "La section n'est pas valide")
}
}
}
person.IsContact = false
person.IsMember = true
person.LastName = data.LastName
person.FirstName = data.FirstName
person.Email = data.Email
person.Phone = data.Phone
person.Mobile = data.Mobile
person.Address1 = data.Address1
person.Address2 = data.Address2
person.PostalCode = data.PostalCode
person.City = data.City
sectionID, err := strconv.ParseUint(data.Section, 10, 0)
if err == nil {
for _, section := range sections {
if section.ID == uint(sectionID) {
person.SectionID = uint(sectionID)
break
}
}
}
if person.SectionID == 0 {
errors = append(errors, "La section est introuvable")
}
if len(errors) == 0 {
result := db.Save(&person)
if result.Error != nil {
return result.Error
} else {
c.Redirect(fmt.Sprintf(
"/members/%d",
person.ID,
))
}
}
}
return c.Render("person_form", fiber.Map{
"PageTitle": title,
"Person": person,
"Sections": sections,
"Errors": errors,
})
}
func MemberConvert(c *fiber.Ctx) error {
id := c.Params("id")
db, err := helpers.GetDatabase()
if err != nil {
return err
}
var person models.Person
result := db.Find(&person, "id = ?", id)
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return fiber.NewError(fiber.StatusNotFound, "Not found")
}
if result.Error != nil {
return result.Error
}
person.IsContact = true
person.IsMember = false
result = db.Save(&person)
if result.Error != nil {
return result.Error
}
return c.Redirect(fmt.Sprintf(
"/contacts/%d",
person.ID,
))
}
func MemberArchive(c *fiber.Ctx) error {
id := c.Params("id")
db, err := helpers.GetDatabase()
if err != nil {
return err
}
result := db.Delete(&models.Person{}, id)
if result.Error != nil {
return result.Error
}
return c.Redirect(fmt.Sprintf(
"/members/%s",
id,
))
}
func MemberRestore(c *fiber.Ctx) error {
id := c.Params("id")
db, err := helpers.GetDatabase()
if err != nil {
return err
}
result := db.Unscoped().Model(&models.Person{}).Where(
"id = ?", id,
).Update("DeletedAt", nil)
if result.Error != nil {
return result.Error
}
return c.Redirect(fmt.Sprintf(
"/members/%s",
id,
))
}
func MemberPurge(c *fiber.Ctx) error {
id := c.Params("id")
db, err := helpers.GetDatabase()
if err != nil {
return err
}
result := db.Unscoped().Delete(
&models.Person{}, id,
)
if result.Error != nil {
return result.Error
}
return c.Redirect("/members")
}

View file

@ -121,6 +121,12 @@ func main() {
app.Get("/members/:id<int;min(0)>", controllers.MemberShow) app.Get("/members/:id<int;min(0)>", controllers.MemberShow)
app.Get("/members/add", controllers.MemberAdd) app.Get("/members/add", controllers.MemberAdd)
app.Post("/members/add", controllers.MemberAdd) app.Post("/members/add", controllers.MemberAdd)
app.Get("/members/:id<int;min(0)>/edit", controllers.MemberEdit)
app.Post("/members/:id<int;min(0)>/edit", controllers.MemberEdit)
app.Post("/members/:id<int;min(0)>/convert", controllers.MemberConvert)
app.Post("/members/:id<int;min(0)>/archive", controllers.MemberArchive)
app.Post("/members/:id<int;min(0)>/restore", controllers.MemberRestore)
app.Post("/members/:id<int;min(0)>/purge", controllers.MemberPurge)
// Contacts // Contacts
app.Get("/contacts", controllers.Contacts) app.Get("/contacts", controllers.Contacts)

View file

@ -159,45 +159,60 @@
</div> </div>
</div> </div>
<div class="my-4"> <div class="my-5">
{% if Person.IsMember %} {% if Person.IsMember %}
<div class="mb-3"> <div class="row">
<a class="btn btn-md btn-primary" href="/members/{{ Person.ID }}/edit"> <div class="col-md-6">
<i class="bi-pencil-square"></i> <a class="btn btn-md btn-primary" href="/members/{{ Person.ID }}/edit">
Modifier <i class="bi-pencil-square"></i>
</a> Modifier
<form </a>
action="/members/{{ Person.ID }}/convert" <form
method="post" action="/members/{{ Person.ID }}/convert"
class="d-inline p-0" method="post"
> class="d-inline p-0"
<button class="btn btn-md btn-primary areyousure" type="submit"> >
<i class="bi-arrow-repeat"></i> <button class="btn btn-md btn-secondary areyousure" type="submit">
Convertir en contact <i class="bi-arrow-repeat"></i>
</button> Convertir en contact
</form> </button>
</div> </form>
<div> </div>
<form <div class="col-md-6 text-md-end mt-2 mt-md-0">
action="/members/{{ Person.ID }}/archive" {% if Person.DeletedAt.Valid %}
method="post" <form
class="d-inline p-0" action="/members/{{ Person.ID }}/restore"
> method="post"
<button class="btn btn-md btn-warning areyousure" type="submit"> class="d-inline p-0"
<i class="bi-archive"></i> >
Archiver <button class="btn btn-md btn-secondary areyousure" type="submit">
</button> <i class="bi-person-check"></i>
</form> Restaurer
<form </button>
action="/members/{{ Person.ID }}/purge" </form>
method="post" {% else %}
class="d-inline p-0" <form
> action="/members/{{ Person.ID }}/archive"
<button class="btn btn-md btn-danger areyousure" type="submit"> method="post"
<i class="bi-trash3"></i> class="d-inline p-0"
Supprimer >
</button> <button class="btn btn-md btn-secondary areyousure" type="submit">
</form> <i class="bi-person-slash"></i>
Archiver
</button>
</form>
{% endif %}
<form
action="/members/{{ Person.ID }}/purge"
method="post"
class="d-inline p-0"
>
<button class="btn btn-md btn-danger areyousure" type="submit">
<i class="bi-trash3"></i>
Supprimer
</button>
</form>
</div>
</div> </div>
{% else %} {% else %}
<a class="btn btn-md btn-primary" href="/contacts/{{ Person.ID }}/edit"> <a class="btn btn-md btn-primary" href="/contacts/{{ Person.ID }}/edit">

View file

@ -47,7 +47,7 @@
</div> </div>
{% endif %} {% endif %}
<form id="section" method="post"> <form id="person" method="post">
<div class="row mb-3"> <div class="row mb-3">
<label for="last_name" class="form-label col-md-2"> <label for="last_name" class="form-label col-md-2">
@ -165,6 +165,7 @@
name="postal_code" name="postal_code"
placeholder="Code postal" placeholder="Code postal"
pattern="[0-9]{4}" pattern="[0-9]{4}"
value="{{ Person.PostalCode }}"
> >
</div> </div>
<div class="col-md-7 col-lg-8"> <div class="col-md-7 col-lg-8">
@ -204,7 +205,7 @@
</div> </div>
</div> </div>
<div class="my-4"> <div class="my-5">
<button class="btn btn-primary" type="submit"> <button class="btn btn-primary" type="submit">
<i class="me-1 bi-floppy"></i> <i class="me-1 bi-floppy"></i>
Enregistrer Enregistrer