Compare commits

...

4 Commits

Author SHA1 Message Date
5987fadb03 Deleting a reservation 2024-07-25 14:09:42 +02:00
fcd29cc082 Marking a resercation as processed 2024-07-25 13:51:31 +02:00
ca1e72c676 Editing a reservation 2024-07-25 13:29:57 +02:00
d4cf44bb22 Database functions for editing a reservation 2024-07-25 13:13:16 +02:00
8 changed files with 196 additions and 8 deletions

View File

@ -44,8 +44,11 @@ func routes(app *config.AppConfig) http.Handler {
mux.Get("/reservations-new", handlers.Repo.AdminNewReservations)
mux.Get("/reservations-all", handlers.Repo.AdminAllReservations)
mux.Get("/reservations-calendar", handlers.Repo.AdminReservationsCalendar)
mux.Get("/process-reservation/{src}/{id}", handlers.Repo.AdminProcessReservation)
mux.Get("/delete-reservation/{src}/{id}", handlers.Repo.AdminDeleteReservation)
mux.Get("/reservations/{src}/{id}", handlers.Repo.AdminShowReservation)
mux.Post("/reservations/{src}/{id}", handlers.Repo.AdminPostShowReservation)
})
return mux

View File

@ -16,6 +16,8 @@ import (
"strconv"
"strings"
"time"
"github.com/go-chi/chi/v5"
)
// Repo the repository used by the handlers
@ -545,6 +547,7 @@ func (m *Repository) AdminShowReservation(w http.ResponseWriter, r *http.Request
id, err := strconv.Atoi(exploded[4])
if err != nil {
helpers.ServerError(w, err)
return
}
src := exploded[3]
@ -555,6 +558,7 @@ func (m *Repository) AdminShowReservation(w http.ResponseWriter, r *http.Request
res, err := m.DB.GetReservationByID(id)
if err != nil {
helpers.ServerError(w, err)
return
}
data := make(map[string]interface{})
@ -568,7 +572,73 @@ func (m *Repository) AdminShowReservation(w http.ResponseWriter, r *http.Request
})
}
// AdminShowReservation shows the detail of a reservation
func (m *Repository) AdminPostShowReservation(w http.ResponseWriter, r *http.Request) {
if err := r.ParseForm(); err != nil {
helpers.ServerError(w, err)
return
}
exploded := strings.Split(r.RequestURI, "/")
id, err := strconv.Atoi(exploded[4])
if err != nil {
helpers.ServerError(w, err)
return
}
src := exploded[3]
stringMap := make(map[string]string)
stringMap["src"] = src
// get reservation from the database
res, err := m.DB.GetReservationByID(id)
if err != nil {
helpers.ServerError(w, err)
return
}
res.FirstName = r.Form.Get("first_name")
res.LastName = r.Form.Get("last_name")
res.Email = r.Form.Get("email")
res.Phone = r.Form.Get("phone")
// TODO error checking
err = m.DB.UpdateReservation(res)
if err != nil {
helpers.ServerError(w, err)
return
}
m.App.Session.Put(r.Context(), "flash", "Changes saved")
http.Redirect(w, r, fmt.Sprintf("/admin/reservations-%s", src), http.StatusSeeOther)
}
// AdminReservationsCalendar displays the reservation calendar
func (m *Repository) AdminReservationsCalendar(w http.ResponseWriter, r *http.Request) {
render.Template(w, r, "admin-reservations-calendar.page.tmpl", &models.TemplateData{})
}
// AdminProcessReservation marks a reservation as processed
func (m *Repository) AdminProcessReservation(w http.ResponseWriter, r *http.Request) {
id, _ := strconv.Atoi(chi.URLParam(r, "id"))
src := chi.URLParam(r, "src")
_ = m.DB.UpdateProcessedForReservation(id, 1)
m.App.Session.Put(r.Context(), "flash", "Reservation marked as processed")
http.Redirect(w, r, fmt.Sprintf("/admin/reservations-%s", src), http.StatusSeeOther)
}
// AdminDeleteReservation deletes a reservation
func (m *Repository) AdminDeleteReservation(w http.ResponseWriter, r *http.Request) {
id, _ := strconv.Atoi(chi.URLParam(r, "id"))
src := chi.URLParam(r, "src")
_ = m.DB.DeleteReservation(id)
m.App.Session.Put(r.Context(), "flash", fmt.Sprintf("Reservation %d deleted", id))
http.Redirect(w, r, fmt.Sprintf("/admin/reservations-%s", src), http.StatusSeeOther)
}

View File

@ -342,3 +342,47 @@ func (m *postgresDBRepo) GetReservationByID(id int) (models.Reservation, error)
}
return res, nil
}
// UpdateReservation updates a user in the database
func (m *postgresDBRepo) UpdateReservation(r models.Reservation) error {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
query := `update reservations set first_name = $1, last_name = $2, email = $3, phone = $4, updated_at = $5
where id = $6`
_, err := m.DB.ExecContext(ctx, query, r.FirstName, r.LastName, r.Email,
r.Phone, time.Now(), r.ID)
if err != nil {
return err
}
return nil
}
// DeleteReservation deletes one reservation by ID
func (m *postgresDBRepo) DeleteReservation(id int) error {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
query := `delete from reservations where id = $1`
_, err := m.DB.ExecContext(ctx, query, id)
if err != nil {
return err
}
return nil
}
// UpdateProcessedForReservation set processed for a reservation
func (m *postgresDBRepo) UpdateProcessedForReservation(id, processed int) error {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
query := `update reservations set processed = $1 where id = $2`
_, err := m.DB.ExecContext(ctx, query, processed, id)
if err != nil {
return err
}
return nil
}

View File

@ -102,3 +102,17 @@ func (m *testDBRepo) GetReservationByID(id int) (models.Reservation, error) {
return res, nil
}
// UpdateReservation updates a user in the database
func (m *testDBRepo) UpdateReservation(r models.Reservation) error {
return nil
}
func (m *testDBRepo) DeleteReservation(id int) error {
return nil
}
// UpdateProcessedForReservation set processed for a reservation
func (m *testDBRepo) UpdateProcessedForReservation(id, processed int) error {
return nil
}

View File

@ -19,4 +19,7 @@ type DatabaseRepo interface {
AllReservations() ([]models.Reservation, error)
AllNewReservations() ([]models.Reservation, error)
GetReservationByID(id int) (models.Reservation, error)
UpdateReservation(r models.Reservation) error
DeleteReservation(id int) error
UpdateProcessedForReservation(id, processed int) error
}

View File

@ -97,12 +97,6 @@ function Prompt() {
c.didOpen();
}
},
preConfirm: () => {
return [
document.getElementById('start').value,
document.getElementById('end').value,
]
},
})
if (c.callback !== undefined) {

View File

@ -48,9 +48,48 @@ Reservation
<hr>
<input type="submit" class="btn btn-primary" value="Save">
<a href="/admin/reservations-{{$src}}" class="btn btn-warning">Cancel</a>
<div class="float-start">
<input type="submit" class="btn btn-primary" value="Save">
<a href="/admin/reservations-{{$src}}" class="btn btn-warning">Cancel</a>
<a href="#" class="btn btn-info" onclick="processRes({{$res.ID}})">Mark as Processed</a>
</div>
<div class="float-end">
<a href="#" class="btn btn-danger" onclick="deleteRes({{$res.ID}})">Delete</a>
</div>
<!-- clear the float -->
<div class="clearfix"></div>
</form>
</div>
{{end}}
{{define "js"}}
{{$src := index .StringMap "src"}}
<script>
function processRes(id) {
attention.custom({
icon: 'warning',
msg: 'Are you sure?',
callback: function(result) {
if (result != false) {
window.location.href = "/admin/process-reservation/{{$src}}/" + id;
}
}
})
}
function deleteRes(id) {
attention.custom({
icon: 'error',
msg: 'Are you sure?',
callback: function(result) {
if (result != false) {
window.location.href = "/admin/delete-reservation/{{$src}}/" + id;
}
}
})
}
</script>
{{end}}

View File

@ -14,6 +14,7 @@
<!-- plugin css for this page -->
<!-- End plugin css for this page -->
<!-- inject:css -->
<link rel="stylesheet" type="text/css" href="https://unpkg.com/notie/dist/notie.min.css">
<link rel="stylesheet" href="/static/admin/css/style.css">
<!-- endinject -->
<link rel="shortcut icon" href="/static/admin/images/favicon.png" />
@ -25,6 +26,9 @@
label {
font-weight: bold;
}
.notie-container {
z-index: 50000;
}
</style>
{{block "css" .}}
@ -132,8 +136,25 @@
<script src="/static/admin/js/todolist.js"></script>
<!-- endinject -->
<!-- Custom js for this page-->
<script src="https://unpkg.com/notie"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script src="/static/js/app.js"></script>
<script src="/static/admin/js/dashboard.js"></script>
<!-- End custom js for this page-->
<script>
let attention = Prompt()
{{with .Error}}
notify("{{.}}", "error")
{{end}}
{{with .Warning}}
notify("{{.}}", "warning")
{{end}}
{{with .Flash}}
notify("{{.}}", "success")
{{end}}
</script>
{{block "js" .}}
{{end}}